summaryrefslogtreecommitdiff
path: root/compiler/optimizing/intrinsics_x86.cc
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/optimizing/intrinsics_x86.cc')
-rw-r--r--compiler/optimizing/intrinsics_x86.cc69
1 files changed, 48 insertions, 21 deletions
diff --git a/compiler/optimizing/intrinsics_x86.cc b/compiler/optimizing/intrinsics_x86.cc
index 0e32315335..398e4109dc 100644
--- a/compiler/optimizing/intrinsics_x86.cc
+++ b/compiler/optimizing/intrinsics_x86.cc
@@ -25,6 +25,7 @@
#include "data_type-inl.h"
#include "entrypoints/quick/quick_entrypoints.h"
#include "heap_poisoning.h"
+#include "intrinsic_objects.h"
#include "intrinsics.h"
#include "intrinsics_utils.h"
#include "lock_word.h"
@@ -37,6 +38,7 @@
#include "thread-current-inl.h"
#include "utils/x86/assembler_x86.h"
#include "utils/x86/constants_x86.h"
+#include "well_known_classes.h"
namespace art HIDDEN {
@@ -3282,21 +3284,36 @@ static void RequestBaseMethodAddressInRegister(HInvoke* invoke) {
}
}
-void IntrinsicLocationsBuilderX86::VisitIntegerValueOf(HInvoke* invoke) {
+#define VISIT_INTRINSIC(name, low, high, type, start_index) \
+ void IntrinsicLocationsBuilderX86::Visit ##name ##ValueOf(HInvoke* invoke) { \
+ InvokeRuntimeCallingConvention calling_convention; \
+ IntrinsicVisitor::ComputeValueOfLocations( \
+ invoke, \
+ codegen_, \
+ low, \
+ high - low + 1, \
+ Location::RegisterLocation(EAX), \
+ Location::RegisterLocation(calling_convention.GetRegisterAt(0))); \
+ RequestBaseMethodAddressInRegister(invoke); \
+ } \
+ void IntrinsicCodeGeneratorX86::Visit ##name ##ValueOf(HInvoke* invoke) { \
+ IntrinsicVisitor::ValueOfInfo info = \
+ IntrinsicVisitor::ComputeValueOfInfo( \
+ invoke, \
+ codegen_->GetCompilerOptions(), \
+ WellKnownClasses::java_lang_ ##name ##_value, \
+ low, \
+ high - low + 1, \
+ start_index); \
+ HandleValueOf(invoke, info, type); \
+ }
+ BOXED_TYPES(VISIT_INTRINSIC)
+#undef VISIT_INTRINSIC
+
+void IntrinsicCodeGeneratorX86::HandleValueOf(HInvoke* invoke,
+ const IntrinsicVisitor::ValueOfInfo& info,
+ DataType::Type primitive_type) {
DCHECK(invoke->IsInvokeStaticOrDirect());
- InvokeRuntimeCallingConvention calling_convention;
- IntrinsicVisitor::ComputeIntegerValueOfLocations(
- invoke,
- codegen_,
- Location::RegisterLocation(EAX),
- Location::RegisterLocation(calling_convention.GetRegisterAt(0)));
- RequestBaseMethodAddressInRegister(invoke);
-}
-
-void IntrinsicCodeGeneratorX86::VisitIntegerValueOf(HInvoke* invoke) {
- DCHECK(invoke->IsInvokeStaticOrDirect());
- IntrinsicVisitor::IntegerValueOfInfo info =
- IntrinsicVisitor::ComputeIntegerValueOfInfo(invoke, codegen_->GetCompilerOptions());
LocationSummary* locations = invoke->GetLocations();
X86Assembler* assembler = GetAssembler();
@@ -3310,17 +3327,22 @@ void IntrinsicCodeGeneratorX86::VisitIntegerValueOf(HInvoke* invoke) {
if (invoke->InputAt(0)->IsConstant()) {
int32_t value = invoke->InputAt(0)->AsIntConstant()->GetValue();
if (static_cast<uint32_t>(value - info.low) < info.length) {
- // Just embed the j.l.Integer in the code.
- DCHECK_NE(info.value_boot_image_reference, IntegerValueOfInfo::kInvalidReference);
+ // Just embed the object in the code.
+ DCHECK_NE(info.value_boot_image_reference, ValueOfInfo::kInvalidReference);
codegen_->LoadBootImageAddress(
out, info.value_boot_image_reference, invoke->AsInvokeStaticOrDirect());
} 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
+ // TODO: If we JIT, we could allocate the object now, and store it in the
// JIT object table.
allocate_instance();
- __ movl(Address(out, info.value_offset), Immediate(value));
+ codegen_->MoveToMemory(primitive_type,
+ Location::ConstantLocation(invoke->InputAt(0)->AsIntConstant()),
+ out,
+ /* dst_index= */ Register::kNoRegister,
+ /* dst_scale= */ TIMES_1,
+ /* dst_disp= */ info.value_offset);
}
} else {
DCHECK(locations->CanCall());
@@ -3330,7 +3352,7 @@ void IntrinsicCodeGeneratorX86::VisitIntegerValueOf(HInvoke* invoke) {
__ 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.
+ // If the value is within the bounds, load the object directly from the array.
constexpr size_t kElementSize = sizeof(mirror::HeapReference<mirror::Object>);
static_assert((1u << TIMES_4) == sizeof(mirror::HeapReference<mirror::Object>),
"Check heap reference size.");
@@ -3358,9 +3380,14 @@ void IntrinsicCodeGeneratorX86::VisitIntegerValueOf(HInvoke* invoke) {
__ MaybeUnpoisonHeapReference(out);
__ jmp(&done);
__ Bind(&allocate);
- // Otherwise allocate and initialize a new j.l.Integer.
+ // Otherwise allocate and initialize a new object.
allocate_instance();
- __ movl(Address(out, info.value_offset), in);
+ codegen_->MoveToMemory(primitive_type,
+ Location::RegisterLocation(in),
+ out,
+ /* dst_index= */ Register::kNoRegister,
+ /* dst_scale= */ TIMES_1,
+ /* dst_disp= */ info.value_offset);
__ Bind(&done);
}
}