Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(22)

Unified Diff: src/a64/lithium-codegen-a64.cc

Issue 148573005: A64: Synchronize with r16249. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/a64/lithium-codegen-a64.h ('k') | src/a64/stub-cache-a64.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/a64/lithium-codegen-a64.cc
diff --git a/src/a64/lithium-codegen-a64.cc b/src/a64/lithium-codegen-a64.cc
index 1ae2e1235fe5331555adaea22ebc7795054f03a3..9386db39514b692332400ac1093d20cf51332c16 100644
--- a/src/a64/lithium-codegen-a64.cc
+++ b/src/a64/lithium-codegen-a64.cc
@@ -215,6 +215,27 @@ class BranchIfHeapNumber : public BranchGenerator {
};
+// Test the input and branch if it is the specified root value.
+class BranchIfRoot : public BranchGenerator {
+ public:
+ BranchIfRoot(LCodeGen* codegen, const Register& value,
+ Heap::RootListIndex index)
+ : BranchGenerator(codegen), value_(value), index_(index) { }
+
+ virtual void Emit(Label* label) const {
+ __ JumpIfRoot(value_, index_, label);
+ }
+
+ virtual void EmitInverted(Label* label) const {
+ __ JumpIfNotRoot(value_, index_, label);
+ }
+
+ private:
+ const Register& value_;
+ const Heap::RootListIndex index_;
+};
+
+
void LCodeGen::WriteTranslation(LEnvironment* environment,
Translation* translation) {
if (environment == NULL) return;
@@ -569,8 +590,14 @@ void LCodeGen::RecordSafepoint(Safepoint::DeoptMode deopt_mode) {
void LCodeGen::RecordSafepointWithRegisters(LPointerMap* pointers,
int arguments,
Safepoint::DeoptMode deopt_mode) {
+ RecordSafepoint(pointers, Safepoint::kWithRegisters, arguments, deopt_mode);
+}
+
+
+void LCodeGen::RecordSafepointWithRegistersAndDoubles(
+ LPointerMap* pointers, int arguments, Safepoint::DeoptMode deopt_mode) {
RecordSafepoint(
- pointers, Safepoint::kWithRegisters, arguments, deopt_mode);
+ pointers, Safepoint::kWithRegistersAndDoubles, arguments, deopt_mode);
}
@@ -1293,6 +1320,15 @@ void LCodeGen::EmitBranchIfHeapNumber(InstrType instr,
}
+template<class InstrType>
+void LCodeGen::EmitBranchIfRoot(InstrType instr,
+ const Register& value,
+ Heap::RootListIndex index) {
+ BranchIfRoot branch(this, value, index);
+ EmitBranchGeneric(instr, branch);
+}
+
+
void LCodeGen::DoGap(LGap* gap) {
for (int i = LGap::FIRST_INNER_POSITION;
i <= LGap::LAST_INNER_POSITION;
@@ -2226,6 +2262,30 @@ void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) {
}
+void LCodeGen::DoCmpHoleAndBranchD(LCmpHoleAndBranchD* instr) {
+ ASSERT(instr->hydrogen()->representation().IsDouble());
+ FPRegister object = ToDoubleRegister(instr->object());
+ Register temp = ToRegister(instr->temp());
+
+ // If we don't have a NaN, we don't have the hole, so branch now to avoid the
+ // (relatively expensive) hole-NaN check.
+ __ Fcmp(object, object);
+ __ B(vc, instr->FalseLabel(chunk_));
+
+ // We have a NaN, but is it the hole?
+ __ Fmov(temp, object);
+ EmitCompareAndBranch(instr, eq, temp, kHoleNanInt64);
+}
+
+
+void LCodeGen::DoCmpHoleAndBranchT(LCmpHoleAndBranchT* instr) {
+ ASSERT(instr->hydrogen()->representation().IsTagged());
+ Register object = ToRegister(instr->object());
+
+ EmitBranchIfRoot(instr, object, Heap::kTheHoleValueRootIndex);
+}
+
+
void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) {
Register value = ToRegister(instr->value());
Register map = ToRegister(instr->temp());
@@ -2382,7 +2442,7 @@ void LCodeGen::DoCheckFunction(LCheckFunction* instr) {
AllowDeferredHandleDereference smi_check;
if (isolate()->heap()->InNewSpace(*target)) {
Register temp = ToRegister(instr->temp());
- Handle<Cell> cell = isolate()->factory()->NewPropertyCell(target);
+ Handle<Cell> cell = isolate()->factory()->NewCell(target);
__ Mov(temp, Operand(Handle<Object>(cell)));
__ Ldr(temp, FieldMemOperand(temp, Cell::kValueOffset));
__ Cmp(reg, temp);
@@ -2455,6 +2515,8 @@ void LCodeGen::DoDeoptimize(LDeoptimize* instr) {
if (info()->IsStub() && (type == Deoptimizer::EAGER)) {
type = Deoptimizer::LAZY;
}
+
+ Comment(";;; deoptimize: %s", instr->hydrogen()->reason());
Deoptimize(instr->environment(), type);
}
@@ -3483,103 +3545,6 @@ void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) {
}
-void LCodeGen::EmitLoadFieldOrConstantFunction(Register result,
- Register object,
- Handle<Map> type,
- Handle<String> name,
- LEnvironment* env) {
- LookupResult lookup(isolate());
- type->LookupDescriptor(NULL, *name, &lookup);
- ASSERT(lookup.IsFound() || lookup.IsCacheable());
-
- if (lookup.IsField()) {
- int index = lookup.GetLocalFieldIndexFromMap(*type);
- int offset = index * kPointerSize;
- if (index < 0) {
- // Negative property indices are in-object properties, indexed from the
- // end of the fixed part of the object.
- __ Ldr(result, FieldMemOperand(object, offset + type->instance_size()));
- } else {
- // Non-negative property indices are in the properties array.
- __ Ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset));
- __ Ldr(result, FieldMemOperand(result, offset + FixedArray::kHeaderSize));
- }
- } else if (lookup.IsConstant()) {
- Handle<Object> constant(lookup.GetConstantFromMap(*type), isolate());
- __ LoadObject(result, constant);
- } else {
- // Negative lookup. Check prototypes.
- Handle<HeapObject> current(HeapObject::cast((*type)->prototype()));
- Heap* heap = type->GetHeap();
- while (*current != heap->null_value()) {
- __ LoadHeapObject(result, current);
- __ CompareMap(result, result, Handle<Map>(current->map()));
- DeoptimizeIf(ne, env);
- current =
- Handle<HeapObject>(HeapObject::cast(current->map()->prototype()));
- }
- __ LoadRoot(result, Heap::kUndefinedValueRootIndex);
- }
-}
-
-
-void LCodeGen::DoLoadNamedFieldPolymorphic(LLoadNamedFieldPolymorphic* instr) {
- Register object = ToRegister(instr->object());
- Register result = ToRegister(instr->result());
- // The result register is loaded with its value when the object's map has been
- // found. At this point we don't need to hold the map in object_map anymore,
- // so both values can share the same register.
- // However when we need to go through the generic code path, the instruction
- // is MarkedAsCall and both object and result registers will be allocated to
- // x0. Object should not be clobbered until the call to LoadIC. We choose a
- // different arbitrary register for object_map in this case.
- Register object_map = instr->IsMarkedAsCall()
- ? x10
- : result;
-
- int map_count = instr->hydrogen()->types()->length();
- bool need_generic = instr->hydrogen()->need_generic();
-
- if ((map_count == 0) && !need_generic) {
- Deoptimize(instr->environment());
- return;
- }
-
- Handle<String> name = instr->hydrogen()->name();
- Label done;
- __ Ldr(object_map, FieldMemOperand(object, HeapObject::kMapOffset));
- for (int i = 0; i < map_count; i++) {
- bool last = (i == (map_count - 1));
- Handle<Map> map = instr->hydrogen()->types()->at(i);
- Label check_passed;
- __ CompareMap(object_map, map, &check_passed);
- if (last && !need_generic) {
- DeoptimizeIf(ne, instr->environment());
- __ Bind(&check_passed);
- EmitLoadFieldOrConstantFunction(result, object, map, name,
- instr->environment());
- } else {
- Label next;
- __ B(ne, &next);
- __ Bind(&check_passed);
- EmitLoadFieldOrConstantFunction(result, object, map, name,
- instr->environment());
- __ B(&done);
- __ Bind(&next);
- }
- }
- if (need_generic) {
- ASSERT(instr->IsMarkedAsCall());
- // LoadIC expects x2 to hold the name, and x0 to hold the receiver.
- ASSERT(object.Is(x0));
- __ Mov(x2, Operand(name));
- Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
- CallCode(ic, RelocInfo::CODE_TARGET, instr);
- }
- __ Bind(&done);
-}
-
-
void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
// LoadIC expects x2 to hold the name, and x0 to hold the receiver.
ASSERT(ToRegister(instr->object()).is(x0));
@@ -4338,35 +4303,6 @@ void LCodeGen::DoNumberTagD(LNumberTagD* instr) {
Register result = ToRegister(instr->result());
Register temp1 = ToRegister(instr->temp1());
Register temp2 = ToRegister(instr->temp2());
- Label done;
-
- bool convert_hole = false;
- HValue* change_input = instr->hydrogen()->value();
- if (change_input->IsLoadKeyed()) {
- HLoadKeyed* load = HLoadKeyed::cast(change_input);
- convert_hole = load->UsesMustHandleHole();
- }
-
- if (convert_hole) {
- Label no_special_nan_handling, canonicalize;
- // TODO(jbramley): This special case does not exist in bleeding_edge.
- // * Non-NaN inputs are handled as usual.
- // * If the input is the hole, the output is the hole.
- // * If the input is any other NaN, the output is the canonical NaN.
- __ Fcmp(input, 0.0);
- __ B(vc, &no_special_nan_handling);
- __ Fmov(temp1, input);
- __ Cmp(temp1, kHoleNanInt64);
- __ B(ne, &canonicalize);
- __ Mov(result, Operand(factory()->the_hole_value()));
- __ B(&done);
- __ Bind(&canonicalize);
- // TODO(jbramley): Overwriting the input is probably a mistake, but this
- // code is removed in bleeding_edge anyway so it won't be here for long.
- TODO_UNIMPLEMENTED("DoNumberTagD: Fix NaN canonicalization logic.");
- __ Fmov(input, FixedDoubleArray::canonical_not_the_hole_nan_as_double());
- __ Bind(&no_special_nan_handling);
- }
DeferredNumberTagD* deferred = new(zone()) DeferredNumberTagD(this, instr);
if (FLAG_inline_new) {
@@ -4377,7 +4313,6 @@ void LCodeGen::DoNumberTagD(LNumberTagD* instr) {
__ Bind(deferred->exit());
__ Str(input, FieldMemOperand(result, HeapNumber::kValueOffset));
- __ Bind(&done);
}
@@ -4460,34 +4395,24 @@ void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) {
Register input = ToRegister(instr->value());
Register scratch = ToRegister(instr->temp());
DoubleRegister result = ToDoubleRegister(instr->result());
- bool allow_undefined_as_nan = instr->hydrogen()->allow_undefined_as_nan();
+ bool can_convert_undefined_to_nan =
+ instr->hydrogen()->can_convert_undefined_to_nan();
Label done, load_smi;
// Work out what untag mode we're working with.
- NumberUntagDMode mode = NUMBER_CANDIDATE_IS_ANY_TAGGED;
HValue* value = instr->hydrogen()->value();
- if (value->type().IsSmi()) {
- mode = NUMBER_CANDIDATE_IS_SMI;
- } else if (value->IsLoadKeyed()) {
- HLoadKeyed* load = HLoadKeyed::cast(value);
- if (load->UsesMustHandleHole()) {
- if (load->hole_mode() == ALLOW_RETURN_HOLE) {
- mode = NUMBER_CANDIDATE_IS_ANY_TAGGED_CONVERT_HOLE;
- }
- }
- }
+ NumberUntagDMode mode = value->representation().IsSmi()
+ ? NUMBER_CANDIDATE_IS_SMI : NUMBER_CANDIDATE_IS_ANY_TAGGED;
- STATIC_ASSERT(NUMBER_CANDIDATE_IS_ANY_TAGGED_CONVERT_HOLE >
- NUMBER_CANDIDATE_IS_ANY_TAGGED);
- if (mode >= NUMBER_CANDIDATE_IS_ANY_TAGGED) {
+ if (mode == NUMBER_CANDIDATE_IS_ANY_TAGGED) {
__ JumpIfSmi(input, &load_smi);
Label convert_undefined, deopt;
// Heap number map check.
- Label* not_heap_number = allow_undefined_as_nan ? &convert_undefined
- : &deopt;
+ Label* not_heap_number = can_convert_undefined_to_nan ? &convert_undefined
+ : &deopt;
__ Ldr(scratch, FieldMemOperand(input, HeapObject::kMapOffset));
__ JumpIfNotRoot(scratch, Heap::kHeapNumberMapRootIndex, not_heap_number);
@@ -4498,20 +4423,10 @@ void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) {
}
__ B(&done);
- if (allow_undefined_as_nan) {
- Label load_nan;
-
+ if (can_convert_undefined_to_nan) {
__ Bind(&convert_undefined);
- // Convert undefined (and hole) to NaN.
- if (mode == NUMBER_CANDIDATE_IS_ANY_TAGGED_CONVERT_HOLE) {
- __ JumpIfRoot(input, Heap::kUndefinedValueRootIndex, &load_nan);
- __ JumpIfNotRoot(input, Heap::kTheHoleValueRootIndex, &deopt);
- } else {
- ASSERT(mode == NUMBER_CANDIDATE_IS_ANY_TAGGED);
- __ JumpIfNotRoot(input, Heap::kUndefinedValueRootIndex, &deopt);
- }
+ __ JumpIfNotRoot(input, Heap::kUndefinedValueRootIndex, &deopt);
- __ Bind(&load_nan);
__ LoadRoot(scratch, Heap::kNanValueRootIndex);
__ Ldr(result, FieldMemOperand(scratch, HeapNumber::kValueOffset));
__ B(&done);
@@ -5427,12 +5342,13 @@ void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) {
__ RecordWriteField(object, HeapObject::kMapOffset, new_map, temp1,
GetLinkRegisterState(), kDontSaveFPRegs);
} else {
- PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
+ PushSafepointRegistersScope scope(
+ this, Safepoint::kWithRegistersAndDoubles);
__ Mov(x0, object);
__ Mov(x1, Operand(to_map));
TransitionElementsKindStub stub(from_kind, to_kind);
__ CallStub(&stub);
- RecordSafepointWithRegisters(
+ RecordSafepointWithRegistersAndDoubles(
instr->pointer_map(), 0, Safepoint::kNoLazyDeopt);
}
__ Bind(&not_applicable);
« no previous file with comments | « src/a64/lithium-codegen-a64.h ('k') | src/a64/stub-cache-a64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698