Register allocation, i.e., mapping the variables of a programming language to the physical registers of a processor, is a mandatory task for almost every compiler and consumes a significant portion of the compile time. In a just-in-time compiler, compile time is a particular issue because compilation happens during program execution and contributes to the overall application run time. Compilers often use global register allocation approaches, such as graph coloring or linear scan, which only have limited potential for improving compile time since they process a whole method at once. With growing methods sizes, these approaches are reaching their scalability boundary due to their limited flexibility. We developed a novel trace register allocation framework, which competes with global approaches in both, compile time and code quality. Instead of processing a whole method at once, our allocator processes linear code segments (traces) independently and is therefore able to (1) select different allocation strategies based on the characteristics of a trace in order to control the trade-off between compile time and peak performance, and (2) to allocate traces in parallel in order to reduce compilation latency, i.e., the time until the result of a compilation is available. We implemented our approach in GraalVM, a production-quality Java Virtual Machine developed by Oracle. Our experiments verify that, although our allocator works on a non-global scope, it performs equally well (or even better) than a state-of-the-art global allocator. This result is already remarkable, since it refutes the common believe that global register allocation is a necessity for good allocation quality. Furthermore, to demonstrate the flexibility of trace register allocation, we seamlessly reduce register allocation time in a range from