Chromium Code Reviews| 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); |