Chromium Code Reviews| Index: src/ic/accessor-assembler.cc |
| diff --git a/src/ic/accessor-assembler.cc b/src/ic/accessor-assembler.cc |
| index 209727d5808f3bdeb793df9debe090aedf1fa0f2..15a7449673fa93c1f9b0107cca3aa5cb04af2347 100644 |
| --- a/src/ic/accessor-assembler.cc |
| +++ b/src/ic/accessor-assembler.cc |
| @@ -141,6 +141,8 @@ void AccessorAssembler::HandleLoadICHandlerCase( |
| const LoadICParameters* p, Node* handler, Label* miss, |
| ElementSupport support_elements) { |
| Comment("have_handler"); |
| + ExitPoint direct_exit(this); |
| + |
| Variable var_holder(this, MachineRepresentation::kTagged); |
| var_holder.Bind(p->receiver); |
| Variable var_smi_handler(this, MachineRepresentation::kTagged); |
| @@ -157,14 +159,14 @@ void AccessorAssembler::HandleLoadICHandlerCase( |
| Bind(&if_smi_handler); |
| { |
| HandleLoadICSmiHandlerCase(p, var_holder.value(), var_smi_handler.value(), |
| - miss, support_elements); |
| + miss, &direct_exit, support_elements); |
| } |
| Bind(&try_proto_handler); |
| { |
| GotoIf(IsCodeMap(LoadMap(handler)), &call_handler); |
| HandleLoadICProtoHandlerCase(p, handler, &var_holder, &var_smi_handler, |
| - &if_smi_handler, miss, false); |
| + &if_smi_handler, miss, &direct_exit, false); |
| } |
| Bind(&call_handler); |
| @@ -177,7 +179,7 @@ void AccessorAssembler::HandleLoadICHandlerCase( |
| void AccessorAssembler::HandleLoadICSmiHandlerCase( |
| const LoadICParameters* p, Node* holder, Node* smi_handler, Label* miss, |
| - ElementSupport support_elements) { |
| + ExitPoint* exit_point, ElementSupport support_elements) { |
| Variable var_double_value(this, MachineRepresentation::kFloat64); |
| Label rebox_double(this, &var_double_value); |
| @@ -201,7 +203,7 @@ void AccessorAssembler::HandleLoadICSmiHandlerCase( |
| EmitElementLoad(holder, elements, elements_kind, intptr_index, |
| is_jsarray_condition, &if_hole, &rebox_double, |
| &var_double_value, &unimplemented_elements_kind, |
| - out_of_bounds, miss); |
| + out_of_bounds, miss, exit_point); |
| Bind(&unimplemented_elements_kind); |
| { |
| @@ -221,7 +223,7 @@ void AccessorAssembler::HandleLoadICSmiHandlerCase( |
| WordEqual(LoadObjectField(protector_cell, PropertyCell::kValueOffset), |
| SmiConstant(Smi::FromInt(Isolate::kProtectorValid))), |
| miss); |
| - Return(UndefinedConstant()); |
| + exit_point->Return(UndefinedConstant()); |
| } |
| Bind(&property); |
| @@ -245,7 +247,7 @@ void AccessorAssembler::HandleLoadICSmiHandlerCase( |
| { |
| Label is_double(this); |
| GotoIf(IsSetWord<LoadHandler::IsDoubleBits>(handler_word), &is_double); |
| - Return(LoadObjectField(holder, offset)); |
| + exit_point->Return(LoadObjectField(holder, offset)); |
| Bind(&is_double); |
| if (FLAG_unbox_double_fields) { |
| @@ -264,7 +266,7 @@ void AccessorAssembler::HandleLoadICSmiHandlerCase( |
| Node* properties = LoadProperties(holder); |
| Node* value = LoadObjectField(properties, offset); |
| GotoIf(IsSetWord<LoadHandler::IsDoubleBits>(handler_word), &is_double); |
| - Return(value); |
| + exit_point->Return(value); |
| Bind(&is_double); |
| var_double_value.Bind(LoadHeapNumberValue(value)); |
| @@ -272,7 +274,7 @@ void AccessorAssembler::HandleLoadICSmiHandlerCase( |
| } |
| Bind(&rebox_double); |
| - Return(AllocateHeapNumberWithValue(var_double_value.value())); |
| + exit_point->Return(AllocateHeapNumberWithValue(var_double_value.value())); |
| } |
| Bind(&constant); |
| @@ -289,18 +291,18 @@ void AccessorAssembler::HandleLoadICSmiHandlerCase( |
| Label if_accessor_info(this); |
| GotoIf(IsSetWord<LoadHandler::IsAccessorInfoBits>(handler_word), |
| &if_accessor_info); |
| - Return(value); |
| + exit_point->Return(value); |
| Bind(&if_accessor_info); |
| Callable callable = CodeFactory::ApiGetter(isolate()); |
| - TailCallStub(callable, p->context, p->receiver, holder, value); |
| + exit_point->ReturnStub(callable, p->context, p->receiver, holder, value); |
| } |
| } |
| void AccessorAssembler::HandleLoadICProtoHandlerCase( |
| const LoadICParameters* p, Node* handler, Variable* var_holder, |
| Variable* var_smi_handler, Label* if_smi_handler, Label* miss, |
| - bool throw_reference_error_if_nonexistent) { |
| + ExitPoint* exit_point, bool throw_reference_error_if_nonexistent) { |
| DCHECK_EQ(MachineRepresentation::kTagged, var_holder->rep()); |
| DCHECK_EQ(MachineRepresentation::kTagged, var_smi_handler->rep()); |
| @@ -352,9 +354,10 @@ void AccessorAssembler::HandleLoadICProtoHandlerCase( |
| GotoIf(WordNotEqual(maybe_holder_cell, NullConstant()), &load_existent); |
| // This is a handler for a load of a non-existent value. |
| if (throw_reference_error_if_nonexistent) { |
| - TailCallRuntime(Runtime::kThrowReferenceError, p->context, p->name); |
| + exit_point->ReturnRuntime(Runtime::kThrowReferenceError, p->context, |
| + p->name); |
| } else { |
| - Return(UndefinedConstant()); |
| + exit_point->Return(UndefinedConstant()); |
| } |
| Bind(&load_existent); |
| @@ -370,9 +373,10 @@ void AccessorAssembler::HandleLoadICProtoHandlerCase( |
| Bind(&array_handler); |
| { |
| - TailCallStub(CodeFactory::LoadICProtoArray( |
| - isolate(), throw_reference_error_if_nonexistent), |
| - p->context, p->receiver, p->name, p->slot, p->vector, handler); |
| + exit_point->ReturnStub(CodeFactory::LoadICProtoArray( |
| + isolate(), throw_reference_error_if_nonexistent), |
| + p->context, p->receiver, p->name, p->slot, p->vector, |
| + handler); |
| } |
| } |
| @@ -440,7 +444,7 @@ Node* AccessorAssembler::EmitLoadICProtoArrayCheck( |
| void AccessorAssembler::HandleLoadGlobalICHandlerCase( |
| const LoadICParameters* pp, Node* handler, Label* miss, |
| - bool throw_reference_error_if_nonexistent) { |
| + ExitPoint* exit_point, bool throw_reference_error_if_nonexistent) { |
| LoadICParameters p = *pp; |
| DCHECK_NULL(p.receiver); |
| Node* native_context = LoadNativeContext(p.context); |
| @@ -450,11 +454,11 @@ void AccessorAssembler::HandleLoadGlobalICHandlerCase( |
| Variable var_smi_handler(this, MachineRepresentation::kTagged); |
| Label if_smi_handler(this); |
| HandleLoadICProtoHandlerCase(&p, handler, &var_holder, &var_smi_handler, |
| - &if_smi_handler, miss, |
| + &if_smi_handler, miss, exit_point, |
| throw_reference_error_if_nonexistent); |
| Bind(&if_smi_handler); |
| HandleLoadICSmiHandlerCase(&p, var_holder.value(), var_smi_handler.value(), |
| - miss, kOnlyProperties); |
| + miss, exit_point, kOnlyProperties); |
| } |
| void AccessorAssembler::HandleStoreICHandlerCase( |
| @@ -856,13 +860,11 @@ void AccessorAssembler::EmitFastElementsBoundsCheck(Node* object, |
| GotoUnless(UintPtrLessThan(intptr_index, var_length.value()), miss); |
| } |
| -void AccessorAssembler::EmitElementLoad(Node* object, Node* elements, |
| - Node* elements_kind, Node* intptr_index, |
| - Node* is_jsarray_condition, |
| - Label* if_hole, Label* rebox_double, |
| - Variable* var_double_value, |
| - Label* unimplemented_elements_kind, |
| - Label* out_of_bounds, Label* miss) { |
| +void AccessorAssembler::EmitElementLoad( |
| + Node* object, Node* elements, Node* elements_kind, Node* intptr_index, |
| + Node* is_jsarray_condition, Label* if_hole, Label* rebox_double, |
| + Variable* var_double_value, Label* unimplemented_elements_kind, |
| + Label* out_of_bounds, Label* miss, ExitPoint* exit_point) { |
| Label if_typed_array(this), if_fast_packed(this), if_fast_holey(this), |
| if_fast_double(this), if_fast_holey_double(this), if_nonfast(this), |
| if_dictionary(this); |
| @@ -894,7 +896,7 @@ void AccessorAssembler::EmitElementLoad(Node* object, Node* elements, |
| Bind(&if_fast_packed); |
| { |
| Comment("fast packed elements"); |
| - Return(LoadFixedArrayElement(elements, intptr_index)); |
| + exit_point->Return(LoadFixedArrayElement(elements, intptr_index)); |
| } |
| Bind(&if_fast_holey); |
| @@ -902,7 +904,7 @@ void AccessorAssembler::EmitElementLoad(Node* object, Node* elements, |
| Comment("fast holey elements"); |
| Node* element = LoadFixedArrayElement(elements, intptr_index); |
| GotoIf(WordEqual(element, TheHoleConstant()), if_hole); |
| - Return(element); |
| + exit_point->Return(element); |
| } |
| Bind(&if_fast_double); |
| @@ -954,7 +956,7 @@ void AccessorAssembler::EmitElementLoad(Node* object, Node* elements, |
| // Finally, load the value. |
| Node* value_index = EntryToIndex<SeededNumberDictionary>( |
| var_entry.value(), SeededNumberDictionary::kEntryValueIndex); |
| - Return(LoadFixedArrayElement(elements, value_index)); |
| + exit_point->Return(LoadFixedArrayElement(elements, value_index)); |
| } |
| Bind(&if_typed_array); |
| @@ -1000,41 +1002,41 @@ void AccessorAssembler::EmitElementLoad(Node* object, Node* elements, |
| { |
| Comment("UINT8_ELEMENTS"); // Handles UINT8_CLAMPED_ELEMENTS too. |
| Node* element = Load(MachineType::Uint8(), backing_store, intptr_index); |
| - Return(SmiFromWord32(element)); |
| + exit_point->Return(SmiFromWord32(element)); |
| } |
| Bind(&int8_elements); |
| { |
| Comment("INT8_ELEMENTS"); |
| Node* element = Load(MachineType::Int8(), backing_store, intptr_index); |
| - Return(SmiFromWord32(element)); |
| + exit_point->Return(SmiFromWord32(element)); |
| } |
| Bind(&uint16_elements); |
| { |
| Comment("UINT16_ELEMENTS"); |
| Node* index = WordShl(intptr_index, IntPtrConstant(1)); |
| Node* element = Load(MachineType::Uint16(), backing_store, index); |
| - Return(SmiFromWord32(element)); |
| + exit_point->Return(SmiFromWord32(element)); |
| } |
| Bind(&int16_elements); |
| { |
| Comment("INT16_ELEMENTS"); |
| Node* index = WordShl(intptr_index, IntPtrConstant(1)); |
| Node* element = Load(MachineType::Int16(), backing_store, index); |
| - Return(SmiFromWord32(element)); |
| + exit_point->Return(SmiFromWord32(element)); |
| } |
| Bind(&uint32_elements); |
| { |
| Comment("UINT32_ELEMENTS"); |
| Node* index = WordShl(intptr_index, IntPtrConstant(2)); |
| Node* element = Load(MachineType::Uint32(), backing_store, index); |
| - Return(ChangeUint32ToTagged(element)); |
| + exit_point->Return(ChangeUint32ToTagged(element)); |
| } |
| Bind(&int32_elements); |
| { |
| Comment("INT32_ELEMENTS"); |
| Node* index = WordShl(intptr_index, IntPtrConstant(2)); |
| Node* element = Load(MachineType::Int32(), backing_store, index); |
| - Return(ChangeInt32ToTagged(element)); |
| + exit_point->Return(ChangeInt32ToTagged(element)); |
| } |
| Bind(&float32_elements); |
| { |
| @@ -1101,6 +1103,9 @@ void AccessorAssembler::GenericElementLoad(Node* receiver, Node* receiver_map, |
| Node* instance_type, Node* index, |
| Label* slow) { |
| Comment("integer index"); |
| + |
| + ExitPoint direct_exit(this); |
| + |
| Label if_element_hole(this), if_oob(this); |
| // Receivers requiring non-standard element accesses (interceptors, access |
| // checks, strings and string wrappers, proxies) are handled in the runtime. |
| @@ -1119,8 +1124,8 @@ void AccessorAssembler::GenericElementLoad(Node* receiver, Node* receiver_map, |
| IncrementCounter(isolate()->counters()->ic_keyed_load_generic_smi(), 1); |
| EmitElementLoad(receiver, elements, elements_kind, index, |
| is_jsarray_condition, &if_element_hole, &rebox_double, |
| - &var_double_value, unimplemented_elements_kind, &if_oob, |
| - slow); |
| + &var_double_value, unimplemented_elements_kind, &if_oob, slow, |
| + &direct_exit); |
| Bind(&rebox_double); |
| Return(AllocateHeapNumberWithValue(var_double_value.value())); |
| @@ -1459,6 +1464,8 @@ void AccessorAssembler::LoadICProtoArray( |
| CSA_ASSERT(this, Word32BinaryNot(TaggedIsSmi(handler))); |
| CSA_ASSERT(this, IsFixedArrayMap(LoadMap(handler))); |
| + ExitPoint direct_exit(this); |
| + |
| Node* smi_handler = LoadObjectField(handler, LoadHandler::kSmiHandlerOffset); |
| Node* handler_flags = SmiUntag(smi_handler); |
| @@ -1468,7 +1475,8 @@ void AccessorAssembler::LoadICProtoArray( |
| EmitLoadICProtoArrayCheck(p, handler, handler_length, handler_flags, |
| &miss, throw_reference_error_if_nonexistent); |
| - HandleLoadICSmiHandlerCase(p, holder, smi_handler, &miss, kOnlyProperties); |
| + HandleLoadICSmiHandlerCase(p, holder, smi_handler, &miss, &direct_exit, |
| + kOnlyProperties); |
| Bind(&miss); |
| { |
| @@ -1477,36 +1485,42 @@ void AccessorAssembler::LoadICProtoArray( |
| } |
| } |
| -void AccessorAssembler::LoadGlobalIC(const LoadICParameters* p, |
| - TypeofMode typeof_mode) { |
| - Label try_handler(this), call_handler(this), miss(this); |
| +void AccessorAssembler::LoadGlobalICData(const LoadICParameters* p, |
|
Igor Sheludko
2017/02/08 15:26:31
LoadGlobalIC_TryPropertyCellCase(Node* vector, Nod
jgruber
2017/02/09 09:23:42
SG. I had it like this in an upcoming CL to omit u
|
| + ExitPoint* exit_point, |
| + Label* try_handler, Label* miss) { |
| + Comment("LoadGlobalICData"); |
|
Igor Sheludko
2017/02/08 15:26:31
Same here.
jgruber
2017/02/09 09:23:42
Done.
|
| + |
| Node* weak_cell = |
| LoadFixedArrayElement(p->vector, p->slot, 0, SMI_PARAMETERS); |
| CSA_ASSERT(this, HasInstanceType(weak_cell, WEAK_CELL_TYPE)); |
| // Load value or try handler case if the {weak_cell} is cleared. |
| - Node* property_cell = LoadWeakCellValue(weak_cell, &try_handler); |
| + Node* property_cell = LoadWeakCellValue(weak_cell, try_handler); |
| CSA_ASSERT(this, HasInstanceType(property_cell, PROPERTY_CELL_TYPE)); |
| Node* value = LoadObjectField(property_cell, PropertyCell::kValueOffset); |
| - GotoIf(WordEqual(value, TheHoleConstant()), &miss); |
| - Return(value); |
| + GotoIf(WordEqual(value, TheHoleConstant()), miss); |
| + exit_point->Return(value); |
| +} |
| - Node* handler; |
| - Bind(&try_handler); |
| - { |
| - handler = |
| - LoadFixedArrayElement(p->vector, p->slot, kPointerSize, SMI_PARAMETERS); |
| - CSA_ASSERT(this, Word32BinaryNot(TaggedIsSmi(handler))); |
| - GotoIf(WordEqual(handler, LoadRoot(Heap::kuninitialized_symbolRootIndex)), |
| - &miss); |
| - GotoIf(IsCodeMap(LoadMap(handler)), &call_handler); |
| +void AccessorAssembler::LoadGlobalICHandler(const LoadICParameters* p, |
|
Igor Sheludko
2017/02/08 15:26:31
LoadGlobalIC_TryHandlerCase
jgruber
2017/02/09 09:23:42
Done.
|
| + TypeofMode typeof_mode, |
| + ExitPoint* exit_point, |
| + Label* miss) { |
| + Comment("LoadGlobalICHandler"); |
|
Igor Sheludko
2017/02/08 15:26:31
Same here.
jgruber
2017/02/09 09:23:42
Done.
|
| - bool throw_reference_error_if_nonexistent = |
| - typeof_mode == NOT_INSIDE_TYPEOF; |
| - HandleLoadGlobalICHandlerCase(p, handler, &miss, |
| - throw_reference_error_if_nonexistent); |
| - } |
| + Label call_handler(this); |
| + |
| + Node* handler = |
| + LoadFixedArrayElement(p->vector, p->slot, kPointerSize, SMI_PARAMETERS); |
| + CSA_ASSERT(this, Word32BinaryNot(TaggedIsSmi(handler))); |
| + GotoIf(WordEqual(handler, LoadRoot(Heap::kuninitialized_symbolRootIndex)), |
| + miss); |
| + GotoIf(IsCodeMap(LoadMap(handler)), &call_handler); |
| + |
| + bool throw_reference_error_if_nonexistent = typeof_mode == NOT_INSIDE_TYPEOF; |
| + HandleLoadGlobalICHandlerCase(p, handler, miss, exit_point, |
| + throw_reference_error_if_nonexistent); |
| Bind(&call_handler); |
| { |
| @@ -1514,14 +1528,31 @@ void AccessorAssembler::LoadGlobalIC(const LoadICParameters* p, |
| Node* native_context = LoadNativeContext(p->context); |
| Node* receiver = |
| LoadContextElement(native_context, Context::EXTENSION_INDEX); |
| - TailCallStub(descriptor, handler, p->context, receiver, p->name, p->slot, |
| - p->vector); |
| + exit_point->ReturnStub(descriptor, handler, p->context, receiver, p->name, |
| + p->slot, p->vector); |
| } |
| +} |
| + |
| +void AccessorAssembler::LoadGlobalICMiss(const LoadICParameters* p, |
| + ExitPoint* exit_point) { |
| + Comment("LoadGlobalICMiss"); |
| + |
| + exit_point->ReturnRuntime(Runtime::kLoadGlobalIC_Miss, p->context, p->name, |
| + p->slot, p->vector); |
| +} |
| + |
| +void AccessorAssembler::LoadGlobalIC(const LoadICParameters* p, |
| + TypeofMode typeof_mode) { |
| + ExitPoint direct_exit(this); |
| + |
| + Label try_handler(this), miss(this); |
| + LoadGlobalICData(p, &direct_exit, &try_handler, &miss); |
| + |
| + Bind(&try_handler); |
| + LoadGlobalICHandler(p, typeof_mode, &direct_exit, &miss); |
| + |
| Bind(&miss); |
| - { |
| - TailCallRuntime(Runtime::kLoadGlobalIC_Miss, p->context, p->name, p->slot, |
| - p->vector); |
| - } |
| + LoadGlobalICMiss(p, &direct_exit); |
| } |
| void AccessorAssembler::KeyedLoadIC(const LoadICParameters* p) { |
| @@ -1829,8 +1860,10 @@ void AccessorAssembler::GenerateLoadField() { |
| Node* context = Parameter(Descriptor::kContext); |
| LoadICParameters p(context, receiver, name, slot, vector); |
| + ExitPoint direct_exit(this); |
| + |
| HandleLoadICSmiHandlerCase(&p, receiver, Parameter(Descriptor::kSmiHandler), |
| - nullptr, kOnlyProperties); |
| + nullptr, &direct_exit, kOnlyProperties); |
| } |
| void AccessorAssembler::GenerateLoadGlobalIC(TypeofMode typeof_mode) { |