Index: src/code-stub-assembler.cc |
diff --git a/src/code-stub-assembler.cc b/src/code-stub-assembler.cc |
index b2f6114f57d466076fe6753497c99768fa7b306a..4dc645e2ae0d82636e8da18caf319631c3652f3b 100644 |
--- a/src/code-stub-assembler.cc |
+++ b/src/code-stub-assembler.cc |
@@ -2977,6 +2977,68 @@ void CodeStubAssembler::TryProbeStubCache( |
} |
} |
+void CodeStubAssembler::HaveLoadICHandler(const LoadICParameters* p, |
Jakob Kummerow
2016/07/26 14:43:28
This entire function has been pulled out from belo
Igor Sheludko
2016/07/26 16:25:11
How about HandleLoadICHandlerCase() or something s
Jakob Kummerow
2016/07/26 17:10:39
Done.
|
+ Node* handler) { |
+ Comment("have_handler"); |
+ Label call_handler(this); |
+ GotoUnless(WordIsSmi(handler), &call_handler); |
+ |
+ // |handler| is a Smi. It encodes a field index as obtained by |
+ // FieldIndex.GetLoadByFieldOffset(). |
+ // TODO(jkummerow): For KeyedLoadICs, extend this scheme to encode |
+ // fast *element* loads. |
+ { |
+ Label inobject_double(this), out_of_object(this), |
+ out_of_object_double(this); |
+ Variable var_double_value(this, MachineRepresentation::kFloat64); |
+ Label rebox_double(this, &var_double_value); |
+ |
+ Node* handler_word = SmiToWord32(handler); |
+ // handler == (offset << 1) | is_double. |
+ Node* double_bit = Word32And(handler_word, Int32Constant(1)); |
+ Node* offset = Word32Sar(handler_word, Int32Constant(1)); |
+ |
+ // Negative index -> out of object. |
+ GotoIf(Int32LessThan(offset, Int32Constant(0)), &out_of_object); |
+ |
+ Node* offset_ptr = ChangeInt32ToIntPtr(offset); |
+ GotoUnless(Word32Equal(double_bit, Int32Constant(0)), &inobject_double); |
+ Return(LoadObjectField(p->receiver, offset_ptr)); |
+ |
+ Bind(&inobject_double); |
+ if (FLAG_unbox_double_fields) { |
+ var_double_value.Bind( |
+ LoadObjectField(p->receiver, offset_ptr, MachineType::Float64())); |
+ } else { |
+ Node* mutable_heap_number = LoadObjectField(p->receiver, offset_ptr); |
+ var_double_value.Bind(LoadHeapNumberValue(mutable_heap_number)); |
+ } |
+ Goto(&rebox_double); |
+ |
+ Bind(&out_of_object); |
+ // |offset| == -actual_offset |
+ offset_ptr = ChangeInt32ToIntPtr(Int32Sub(Int32Constant(0), offset)); |
+ Node* properties = LoadProperties(p->receiver); |
+ Node* value = LoadObjectField(properties, offset_ptr); |
+ GotoUnless(Word32Equal(double_bit, Int32Constant(0)), |
+ &out_of_object_double); |
+ Return(value); |
+ |
+ Bind(&out_of_object_double); |
+ var_double_value.Bind(LoadHeapNumberValue(value)); |
+ Goto(&rebox_double); |
+ |
+ Bind(&rebox_double); |
+ Return(AllocateHeapNumberWithValue(var_double_value.value())); |
+ } |
+ |
+ // |handler| is a heap object. Must be code, call it. |
+ Bind(&call_handler); |
+ LoadWithVectorDescriptor descriptor(isolate()); |
+ TailCallStub(descriptor, handler, p->context, p->receiver, p->name, p->slot, |
+ p->vector); |
+} |
+ |
void CodeStubAssembler::LoadIC(const LoadICParameters* p) { |
Variable var_handler(this, MachineRepresentation::kTagged); |
// TODO(ishell): defer blocks when it works. |
@@ -2991,63 +3053,7 @@ void CodeStubAssembler::LoadIC(const LoadICParameters* p) { |
&var_handler, &try_polymorphic); |
Bind(&if_handler); |
{ |
- Comment("LoadIC_if_handler"); |
- Label call_handler(this); |
- Node* handler = var_handler.value(); |
- GotoUnless(WordIsSmi(handler), &call_handler); |
- |
- // |handler| is a Smi. It encodes a field index as obtained by |
- // FieldIndex.GetLoadByFieldOffset(). |
- { |
- Label inobject_double(this), out_of_object(this), |
- out_of_object_double(this); |
- Variable var_double_value(this, MachineRepresentation::kFloat64); |
- Label rebox_double(this, &var_double_value); |
- |
- Node* handler_word = SmiToWord32(handler); |
- // handler == (offset << 1) | is_double. |
- Node* double_bit = Word32And(handler_word, Int32Constant(1)); |
- Node* offset = Word32Sar(handler_word, Int32Constant(1)); |
- |
- // Negative index -> out of object. |
- GotoIf(Int32LessThan(offset, Int32Constant(0)), &out_of_object); |
- |
- Node* offset_ptr = ChangeInt32ToIntPtr(offset); |
- GotoUnless(Word32Equal(double_bit, Int32Constant(0)), &inobject_double); |
- Return(LoadObjectField(p->receiver, offset_ptr)); |
- |
- Bind(&inobject_double); |
- if (FLAG_unbox_double_fields) { |
- var_double_value.Bind( |
- LoadObjectField(p->receiver, offset_ptr, MachineType::Float64())); |
- } else { |
- Node* mutable_heap_number = LoadObjectField(p->receiver, offset_ptr); |
- var_double_value.Bind(LoadHeapNumberValue(mutable_heap_number)); |
- } |
- Goto(&rebox_double); |
- |
- Bind(&out_of_object); |
- // |offset| == -actual_offset |
- offset_ptr = ChangeInt32ToIntPtr(Int32Sub(Int32Constant(0), offset)); |
- Node* properties = LoadProperties(p->receiver); |
- Node* value = LoadObjectField(properties, offset_ptr); |
- GotoUnless(Word32Equal(double_bit, Int32Constant(0)), |
- &out_of_object_double); |
- Return(value); |
- |
- Bind(&out_of_object_double); |
- var_double_value.Bind(LoadHeapNumberValue(value)); |
- Goto(&rebox_double); |
- |
- Bind(&rebox_double); |
- Return(AllocateHeapNumberWithValue(var_double_value.value())); |
- } |
- |
- // |handler| is a heap object. Must be code, call it. |
- Bind(&call_handler); |
- LoadWithVectorDescriptor descriptor(isolate()); |
- TailCallStub(descriptor, handler, p->context, p->receiver, p->name, p->slot, |
- p->vector); |
+ HaveLoadICHandler(p, var_handler.value()); |
} |
Bind(&try_polymorphic); |