Index: src/ic/accessor-assembler.cc |
diff --git a/src/ic/accessor-assembler.cc b/src/ic/accessor-assembler.cc |
index 209727d5808f3bdeb793df9debe090aedf1fa0f2..b0653a1ab2c755cfdadba90fd8821f032c6c4c1a 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,19 @@ 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->ReturnCallStub(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 +355,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->ReturnCallRuntime(Runtime::kThrowReferenceError, p->context, |
+ p->name); |
} else { |
- Return(UndefinedConstant()); |
+ exit_point->Return(UndefinedConstant()); |
} |
Bind(&load_existent); |
@@ -370,9 +374,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->ReturnCallStub( |
+ CodeFactory::LoadICProtoArray(isolate(), |
+ throw_reference_error_if_nonexistent), |
+ p->context, p->receiver, p->name, p->slot, p->vector, handler); |
} |
} |
@@ -440,7 +445,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 +455,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 +861,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 +897,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 +905,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 +957,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 +1003,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 +1104,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 +1125,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 +1465,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 +1476,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 +1486,41 @@ void AccessorAssembler::LoadICProtoArray( |
} |
} |
-void AccessorAssembler::LoadGlobalIC(const LoadICParameters* p, |
- TypeofMode typeof_mode) { |
- Label try_handler(this), call_handler(this), miss(this); |
- Node* weak_cell = |
- LoadFixedArrayElement(p->vector, p->slot, 0, SMI_PARAMETERS); |
+void AccessorAssembler::LoadGlobalIC_TryPropertyCellCase( |
+ Node* vector, Node* slot, ExitPoint* exit_point, Label* try_handler, |
+ Label* miss, ParameterMode slot_mode) { |
+ Comment("LoadGlobalIC_TryPropertyCellCase"); |
+ |
+ Node* weak_cell = LoadFixedArrayElement(vector, slot, 0, slot_mode); |
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::LoadGlobalIC_TryHandlerCase(const LoadICParameters* p, |
+ TypeofMode typeof_mode, |
+ ExitPoint* exit_point, |
+ Label* miss) { |
+ Comment("LoadGlobalIC_TryHandlerCase"); |
- 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,32 @@ 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->ReturnCallStub(descriptor, handler, p->context, receiver, |
+ p->name, p->slot, p->vector); |
} |
+} |
+ |
+void AccessorAssembler::LoadGlobalIC_MissCase(const LoadICParameters* p, |
+ ExitPoint* exit_point) { |
+ Comment("LoadGlobalIC_MissCase"); |
+ |
+ exit_point->ReturnCallRuntime(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); |
+ LoadGlobalIC_TryPropertyCellCase(p->vector, p->slot, &direct_exit, |
+ &try_handler, &miss); |
+ |
+ Bind(&try_handler); |
+ LoadGlobalIC_TryHandlerCase(p, typeof_mode, &direct_exit, &miss); |
+ |
Bind(&miss); |
- { |
- TailCallRuntime(Runtime::kLoadGlobalIC_Miss, p->context, p->name, p->slot, |
- p->vector); |
- } |
+ LoadGlobalIC_MissCase(p, &direct_exit); |
} |
void AccessorAssembler::KeyedLoadIC(const LoadICParameters* p) { |
@@ -1829,8 +1861,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) { |