diff options
Diffstat (limited to 'compiler/optimizing/intrinsics_x86_64.cc')
-rw-r--r-- | compiler/optimizing/intrinsics_x86_64.cc | 39 |
1 files changed, 15 insertions, 24 deletions
diff --git a/compiler/optimizing/intrinsics_x86_64.cc b/compiler/optimizing/intrinsics_x86_64.cc index 7627dc9490..6d85f3a1ac 100644 --- a/compiler/optimizing/intrinsics_x86_64.cc +++ b/compiler/optimizing/intrinsics_x86_64.cc @@ -2660,56 +2660,47 @@ void IntrinsicLocationsBuilderX86_64::VisitIntegerValueOf(HInvoke* invoke) { } void IntrinsicCodeGeneratorX86_64::VisitIntegerValueOf(HInvoke* invoke) { - IntrinsicVisitor::IntegerValueOfInfo info = IntrinsicVisitor::ComputeIntegerValueOfInfo(); + IntrinsicVisitor::IntegerValueOfInfo info = IntrinsicVisitor::ComputeIntegerValueOfInfo(invoke); LocationSummary* locations = invoke->GetLocations(); X86_64Assembler* assembler = GetAssembler(); CpuRegister out = locations->Out().AsRegister<CpuRegister>(); InvokeRuntimeCallingConvention calling_convention; - if (invoke->InputAt(0)->IsConstant()) { + CpuRegister argument = CpuRegister(calling_convention.GetRegisterAt(0)); + if (invoke->InputAt(0)->IsIntConstant()) { int32_t value = invoke->InputAt(0)->AsIntConstant()->GetValue(); - if (value >= info.low && value <= info.high) { + if (info.value_boot_image_offset != 0u) { // Just embed the j.l.Integer in the code. - ScopedObjectAccess soa(Thread::Current()); - mirror::Object* boxed = info.cache->Get(value + (-info.low)); - DCHECK(boxed != nullptr && Runtime::Current()->GetHeap()->ObjectIsInBootImageSpace(boxed)); - uint32_t address = dchecked_integral_cast<uint32_t>(reinterpret_cast<uintptr_t>(boxed)); - __ movl(out, Immediate(static_cast<int32_t>(address))); + codegen_->LoadBootImageAddress(out, info.value_boot_image_offset); } else { + DCHECK(locations->CanCall()); // Allocate and initialize a new j.l.Integer. // TODO: If we JIT, we could allocate the j.l.Integer now, and store it in the // JIT object table. - CpuRegister argument = CpuRegister(calling_convention.GetRegisterAt(0)); - uint32_t address = dchecked_integral_cast<uint32_t>(reinterpret_cast<uintptr_t>(info.integer)); - __ movl(argument, Immediate(static_cast<int32_t>(address))); + codegen_->LoadBootImageAddress(argument, info.integer_boot_image_offset); codegen_->InvokeRuntime(kQuickAllocObjectInitialized, invoke, invoke->GetDexPc()); CheckEntrypointTypes<kQuickAllocObjectWithChecks, void*, mirror::Class*>(); __ movl(Address(out, info.value_offset), Immediate(value)); } } else { + DCHECK(locations->CanCall()); CpuRegister in = locations->InAt(0).AsRegister<CpuRegister>(); // Check bounds of our cache. __ leal(out, Address(in, -info.low)); - __ cmpl(out, Immediate(info.high - info.low + 1)); + __ cmpl(out, Immediate(info.length)); NearLabel allocate, done; __ j(kAboveEqual, &allocate); // If the value is within the bounds, load the j.l.Integer directly from the array. - uint32_t data_offset = mirror::Array::DataOffset(kHeapReferenceSize).Uint32Value(); - uint32_t address = dchecked_integral_cast<uint32_t>(reinterpret_cast<uintptr_t>(info.cache)); - if (data_offset + address <= std::numeric_limits<int32_t>::max()) { - __ movl(out, Address(out, TIMES_4, data_offset + address)); - } else { - CpuRegister temp = CpuRegister(calling_convention.GetRegisterAt(0)); - __ movl(temp, Immediate(static_cast<int32_t>(data_offset + address))); - __ movl(out, Address(temp, out, TIMES_4, 0)); - } + DCHECK_NE(out.AsRegister(), argument.AsRegister()); + codegen_->LoadBootImageAddress(argument, info.array_data_boot_image_offset); + static_assert((1u << TIMES_4) == sizeof(mirror::HeapReference<mirror::Object>), + "Check heap reference size."); + __ movl(out, Address(argument, out, TIMES_4, 0)); __ MaybeUnpoisonHeapReference(out); __ jmp(&done); __ Bind(&allocate); // Otherwise allocate and initialize a new j.l.Integer. - CpuRegister argument = CpuRegister(calling_convention.GetRegisterAt(0)); - address = dchecked_integral_cast<uint32_t>(reinterpret_cast<uintptr_t>(info.integer)); - __ movl(argument, Immediate(static_cast<int32_t>(address))); + codegen_->LoadBootImageAddress(argument, info.integer_boot_image_offset); codegen_->InvokeRuntime(kQuickAllocObjectInitialized, invoke, invoke->GetDexPc()); CheckEntrypointTypes<kQuickAllocObjectWithChecks, void*, mirror::Class*>(); __ movl(Address(out, info.value_offset), in); |