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

Unified Diff: src/code-stub-assembler.cc

Issue 2498013002: [ic] Refactor LoadIC code. (Closed)
Patch Set: Created 4 years, 1 month 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/code-stub-assembler.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/code-stub-assembler.cc
diff --git a/src/code-stub-assembler.cc b/src/code-stub-assembler.cc
index 323c05d17e737cbbfdc0e5acfb1dc6625743b867..a6dc02cd7fc2b0f0309ec057aec336c3a8f0bd14 100644
--- a/src/code-stub-assembler.cc
+++ b/src/code-stub-assembler.cc
@@ -5509,145 +5509,148 @@ void CodeStubAssembler::HandleLoadICHandlerCase(
// for the encoding format.
Bind(&if_smi_handler);
{
- Variable var_double_value(this, MachineRepresentation::kFloat64);
Igor Sheludko 2016/11/14 18:08:54 This whole piece of code was moved to HandleLoadIC
- Label rebox_double(this, &var_double_value);
+ HandleLoadICSmiHandlerCase(p, var_holder.value(), var_smi_handler.value(),
+ miss, support_elements);
+ }
- Node* holder = var_holder.value();
- Node* handler_word = SmiUntag(var_smi_handler.value());
- Node* handler_kind = DecodeWord<LoadHandler::KindBits>(handler_word);
- if (support_elements == kSupportElements) {
- Label property(this);
- GotoUnless(
- WordEqual(handler_kind, IntPtrConstant(LoadHandler::kForElements)),
- &property);
-
- Comment("element_load");
- Node* intptr_index = TryToIntptr(p->name, miss);
- Node* elements = LoadElements(holder);
- Node* is_jsarray_condition =
- IsSetWord<LoadHandler::IsJsArrayBits>(handler_word);
- Node* elements_kind =
- DecodeWord<LoadHandler::ElementsKindBits>(handler_word);
- Label if_hole(this), unimplemented_elements_kind(this);
- Label* out_of_bounds = miss;
- EmitElementLoad(holder, elements, elements_kind, intptr_index,
- is_jsarray_condition, &if_hole, &rebox_double,
- &var_double_value, &unimplemented_elements_kind,
- out_of_bounds, miss);
-
- Bind(&unimplemented_elements_kind);
- {
- // Smi handlers should only be installed for supported elements kinds.
- // Crash if we get here.
- DebugBreak();
- Goto(miss);
- }
+ Bind(&try_proto_handler);
+ {
+ GotoIf(IsCodeMap(LoadMap(handler)), &call_handler);
+ HandleLoadICProtoHandler(p, handler, &var_holder, &var_smi_handler,
+ &if_smi_handler, miss);
+ }
- Bind(&if_hole);
- {
- Comment("convert hole");
- GotoUnless(IsSetWord<LoadHandler::ConvertHoleBits>(handler_word), miss);
- Node* protector_cell = LoadRoot(Heap::kArrayProtectorRootIndex);
- DCHECK(isolate()->heap()->array_protector()->IsPropertyCell());
- GotoUnless(
- WordEqual(
- LoadObjectField(protector_cell, PropertyCell::kValueOffset),
- SmiConstant(Smi::FromInt(Isolate::kArrayProtectorValid))),
- miss);
- Return(UndefinedConstant());
- }
+ Bind(&call_handler);
+ {
+ typedef LoadWithVectorDescriptor Descriptor;
+ TailCallStub(Descriptor(isolate()), handler, p->context,
+ Arg(Descriptor::kReceiver, p->receiver),
+ Arg(Descriptor::kName, p->name),
+ Arg(Descriptor::kSlot, p->slot),
+ Arg(Descriptor::kVector, p->vector));
+ }
+}
- Bind(&property);
- Comment("property_load");
- }
+void CodeStubAssembler::HandleLoadICSmiHandlerCase(
+ const LoadICParameters* p, Node* holder, Node* smi_handler, Label* miss,
+ ElementSupport support_elements) {
+ Variable var_double_value(this, MachineRepresentation::kFloat64);
+ Label rebox_double(this, &var_double_value);
- Label constant(this), field(this);
- Branch(WordEqual(handler_kind, IntPtrConstant(LoadHandler::kForFields)),
- &field, &constant);
+ Node* handler_word = SmiUntag(smi_handler);
+ Node* handler_kind = DecodeWord<LoadHandler::KindBits>(handler_word);
+ if (support_elements == kSupportElements) {
+ Label property(this);
+ GotoUnless(
+ WordEqual(handler_kind, IntPtrConstant(LoadHandler::kForElements)),
+ &property);
- Bind(&field);
+ Comment("element_load");
+ Node* intptr_index = TryToIntptr(p->name, miss);
+ Node* elements = LoadElements(holder);
+ Node* is_jsarray_condition =
+ IsSetWord<LoadHandler::IsJsArrayBits>(handler_word);
+ Node* elements_kind =
+ DecodeWord<LoadHandler::ElementsKindBits>(handler_word);
+ Label if_hole(this), unimplemented_elements_kind(this);
+ Label* out_of_bounds = miss;
+ EmitElementLoad(holder, elements, elements_kind, intptr_index,
+ is_jsarray_condition, &if_hole, &rebox_double,
+ &var_double_value, &unimplemented_elements_kind,
+ out_of_bounds, miss);
+
+ Bind(&unimplemented_elements_kind);
{
- Comment("field_load");
- Node* offset = DecodeWord<LoadHandler::FieldOffsetBits>(handler_word);
+ // Smi handlers should only be installed for supported elements kinds.
+ // Crash if we get here.
+ DebugBreak();
+ Goto(miss);
+ }
- Label inobject(this), out_of_object(this);
- Branch(IsSetWord<LoadHandler::IsInobjectBits>(handler_word), &inobject,
- &out_of_object);
+ Bind(&if_hole);
+ {
+ Comment("convert hole");
+ GotoUnless(IsSetWord<LoadHandler::ConvertHoleBits>(handler_word), miss);
+ Node* protector_cell = LoadRoot(Heap::kArrayProtectorRootIndex);
+ DCHECK(isolate()->heap()->array_protector()->IsPropertyCell());
+ GotoUnless(
+ WordEqual(LoadObjectField(protector_cell, PropertyCell::kValueOffset),
+ SmiConstant(Smi::FromInt(Isolate::kArrayProtectorValid))),
+ miss);
+ Return(UndefinedConstant());
+ }
- Bind(&inobject);
- {
- Label is_double(this);
- GotoIf(IsSetWord<LoadHandler::IsDoubleBits>(handler_word), &is_double);
- Return(LoadObjectField(holder, offset));
+ Bind(&property);
+ Comment("property_load");
+ }
- Bind(&is_double);
- if (FLAG_unbox_double_fields) {
- var_double_value.Bind(
- LoadObjectField(holder, offset, MachineType::Float64()));
- } else {
- Node* mutable_heap_number = LoadObjectField(holder, offset);
- var_double_value.Bind(LoadHeapNumberValue(mutable_heap_number));
- }
- Goto(&rebox_double);
- }
+ Label constant(this), field(this);
+ Branch(WordEqual(handler_kind, IntPtrConstant(LoadHandler::kForFields)),
+ &field, &constant);
- Bind(&out_of_object);
- {
- Label is_double(this);
- Node* properties = LoadProperties(holder);
- Node* value = LoadObjectField(properties, offset);
- GotoIf(IsSetWord<LoadHandler::IsDoubleBits>(handler_word), &is_double);
- Return(value);
+ Bind(&field);
+ {
+ Comment("field_load");
+ Node* offset = DecodeWord<LoadHandler::FieldOffsetBits>(handler_word);
- Bind(&is_double);
- var_double_value.Bind(LoadHeapNumberValue(value));
- Goto(&rebox_double);
- }
+ Label inobject(this), out_of_object(this);
+ Branch(IsSetWord<LoadHandler::IsInobjectBits>(handler_word), &inobject,
+ &out_of_object);
- Bind(&rebox_double);
- Return(AllocateHeapNumberWithValue(var_double_value.value()));
+ Bind(&inobject);
+ {
+ Label is_double(this);
+ GotoIf(IsSetWord<LoadHandler::IsDoubleBits>(handler_word), &is_double);
+ Return(LoadObjectField(holder, offset));
+
+ Bind(&is_double);
+ if (FLAG_unbox_double_fields) {
+ var_double_value.Bind(
+ LoadObjectField(holder, offset, MachineType::Float64()));
+ } else {
+ Node* mutable_heap_number = LoadObjectField(holder, offset);
+ var_double_value.Bind(LoadHeapNumberValue(mutable_heap_number));
+ }
+ Goto(&rebox_double);
}
- Bind(&constant);
+ Bind(&out_of_object);
{
- Comment("constant_load");
- Node* descriptors = LoadMapDescriptors(LoadMap(holder));
- Node* descriptor =
- DecodeWord<LoadHandler::DescriptorValueIndexBits>(handler_word);
-#if defined(DEBUG)
Igor Sheludko 2016/11/14 18:08:54 I only removed this #ifdef.
- CSA_ASSERT(
- this, UintPtrLessThan(descriptor,
- LoadAndUntagFixedArrayBaseLength(descriptors)));
-#endif
- Node* value =
- LoadFixedArrayElement(descriptors, descriptor, 0, INTPTR_PARAMETERS);
-
- Label if_accessor_info(this);
- GotoIf(IsSetWord<LoadHandler::IsAccessorInfoBits>(handler_word),
- &if_accessor_info);
+ Label is_double(this);
+ Node* properties = LoadProperties(holder);
+ Node* value = LoadObjectField(properties, offset);
+ GotoIf(IsSetWord<LoadHandler::IsDoubleBits>(handler_word), &is_double);
Return(value);
- Bind(&if_accessor_info);
- Callable callable = CodeFactory::ApiGetter(isolate());
- TailCallStub(callable, p->context, p->receiver, holder, value);
+ Bind(&is_double);
+ var_double_value.Bind(LoadHeapNumberValue(value));
+ Goto(&rebox_double);
}
- }
- Bind(&try_proto_handler);
- {
- GotoIf(IsCodeMap(LoadMap(handler)), &call_handler);
- HandleLoadICProtoHandler(p, handler, &var_holder, &var_smi_handler,
- &if_smi_handler, miss);
+ Bind(&rebox_double);
+ Return(AllocateHeapNumberWithValue(var_double_value.value()));
}
- Bind(&call_handler);
+ Bind(&constant);
{
- typedef LoadWithVectorDescriptor Descriptor;
- TailCallStub(Descriptor(isolate()), handler, p->context,
- Arg(Descriptor::kReceiver, p->receiver),
- Arg(Descriptor::kName, p->name),
- Arg(Descriptor::kSlot, p->slot),
- Arg(Descriptor::kVector, p->vector));
+ Comment("constant_load");
+ Node* descriptors = LoadMapDescriptors(LoadMap(holder));
+ Node* descriptor =
+ DecodeWord<LoadHandler::DescriptorValueIndexBits>(handler_word);
+ CSA_ASSERT(this,
+ UintPtrLessThan(descriptor,
+ LoadAndUntagFixedArrayBaseLength(descriptors)));
+ Node* value =
+ LoadFixedArrayElement(descriptors, descriptor, 0, INTPTR_PARAMETERS);
+
+ Label if_accessor_info(this);
+ GotoIf(IsSetWord<LoadHandler::IsAccessorInfoBits>(handler_word),
+ &if_accessor_info);
+ Return(value);
+
+ Bind(&if_accessor_info);
+ Callable callable = CodeFactory::ApiGetter(isolate());
+ TailCallStub(callable, p->context, p->receiver, holder, value);
}
}
@@ -5717,67 +5720,74 @@ void CodeStubAssembler::HandleLoadICProtoHandler(
Bind(&array_handler);
{
- Node* length = SmiUntag(maybe_holder_cell);
-
- Variable start_index(this, MachineType::PointerRepresentation());
Igor Sheludko 2016/11/14 18:08:54 This code block now returns a holder.
- start_index.Bind(IntPtrConstant(LoadHandler::kFirstPrototypeIndex));
+ Node* handler_length = SmiUntag(maybe_holder_cell);
+ Node* holder = EmitLoadICProtoArrayCheck(p, handler, handler_length,
+ handler_flags, miss);
+ var_holder->Bind(holder);
+ var_smi_handler->Bind(smi_handler);
+ Goto(if_smi_handler);
+ }
+}
- Label can_access(this);
- GotoUnless(
- IsSetWord<LoadHandler::DoAccessCheckOnReceiverBits>(handler_flags),
- &can_access);
- {
- // Skip this entry of a handler.
- start_index.Bind(IntPtrConstant(LoadHandler::kFirstPrototypeIndex + 1));
-
- int offset =
- FixedArray::OffsetOfElementAt(LoadHandler::kFirstPrototypeIndex);
- Node* expected_native_context =
- LoadWeakCellValue(LoadObjectField(handler, offset), miss);
- CSA_ASSERT(this, IsNativeContext(expected_native_context));
-
- Node* native_context = LoadNativeContext(p->context);
- GotoIf(WordEqual(expected_native_context, native_context), &can_access);
- // If the receiver is not a JSGlobalProxy then we miss.
- GotoUnless(IsJSGlobalProxy(p->receiver), miss);
- // For JSGlobalProxy receiver try to compare security tokens of current
- // and expected native contexts.
- Node* expected_token = LoadContextElement(expected_native_context,
- Context::SECURITY_TOKEN_INDEX);
- Node* current_token =
- LoadContextElement(native_context, Context::SECURITY_TOKEN_INDEX);
- Branch(WordEqual(expected_token, current_token), &can_access, miss);
- }
- Bind(&can_access);
+Node* CodeStubAssembler::EmitLoadICProtoArrayCheck(const LoadICParameters* p,
+ Node* handler,
+ Node* handler_length,
+ Node* handler_flags,
+ Label* miss) {
+ Variable start_index(this, MachineType::PointerRepresentation());
+ start_index.Bind(IntPtrConstant(LoadHandler::kFirstPrototypeIndex));
- BuildFastLoop(MachineType::PointerRepresentation(), start_index.value(),
- length,
- [this, p, handler, miss](CodeStubAssembler*, Node* current) {
- Node* prototype_cell = LoadFixedArrayElement(
- handler, current, 0, INTPTR_PARAMETERS);
- CheckPrototype(prototype_cell, p->name, miss);
- },
- 1, IndexAdvanceMode::kPost);
+ Label can_access(this);
+ GotoUnless(IsSetWord<LoadHandler::DoAccessCheckOnReceiverBits>(handler_flags),
+ &can_access);
+ {
+ // Skip this entry of a handler.
+ start_index.Bind(IntPtrConstant(LoadHandler::kFirstPrototypeIndex + 1));
- Node* maybe_holder_cell = LoadFixedArrayElement(
- handler, IntPtrConstant(LoadHandler::kHolderCellIndex), 0,
- INTPTR_PARAMETERS);
- Label load_existent(this);
- GotoIf(WordNotEqual(maybe_holder_cell, NullConstant()), &load_existent);
- // This is a handler for a load of a non-existent value.
- Return(UndefinedConstant());
+ int offset =
+ FixedArray::OffsetOfElementAt(LoadHandler::kFirstPrototypeIndex);
+ Node* expected_native_context =
+ LoadWeakCellValue(LoadObjectField(handler, offset), miss);
+ CSA_ASSERT(this, IsNativeContext(expected_native_context));
- Bind(&load_existent);
- Node* holder = LoadWeakCellValue(maybe_holder_cell);
- // The |holder| is guaranteed to be alive at this point since we passed
- // the receiver map check, the validity cell check and the prototype chain
- // check.
- CSA_ASSERT(this, WordNotEqual(holder, IntPtrConstant(0)));
+ Node* native_context = LoadNativeContext(p->context);
+ GotoIf(WordEqual(expected_native_context, native_context), &can_access);
+ // If the receiver is not a JSGlobalProxy then we miss.
+ GotoUnless(IsJSGlobalProxy(p->receiver), miss);
+ // For JSGlobalProxy receiver try to compare security tokens of current
+ // and expected native contexts.
+ Node* expected_token = LoadContextElement(expected_native_context,
+ Context::SECURITY_TOKEN_INDEX);
+ Node* current_token =
+ LoadContextElement(native_context, Context::SECURITY_TOKEN_INDEX);
+ Branch(WordEqual(expected_token, current_token), &can_access, miss);
+ }
+ Bind(&can_access);
- var_holder->Bind(holder);
- var_smi_handler->Bind(smi_handler);
- Goto(if_smi_handler);
- }
+ BuildFastLoop(
+ MachineType::PointerRepresentation(), start_index.value(), handler_length,
+ [this, p, handler, miss](CodeStubAssembler*, Node* current) {
+ Node* prototype_cell =
+ LoadFixedArrayElement(handler, current, 0, INTPTR_PARAMETERS);
+ CheckPrototype(prototype_cell, p->name, miss);
+ },
+ 1, IndexAdvanceMode::kPost);
+
+ Node* maybe_holder_cell = LoadFixedArrayElement(
+ handler, IntPtrConstant(LoadHandler::kHolderCellIndex), 0,
+ INTPTR_PARAMETERS);
+ Label load_existent(this);
+ GotoIf(WordNotEqual(maybe_holder_cell, NullConstant()), &load_existent);
+ // This is a handler for a load of a non-existent value.
+ Return(UndefinedConstant());
+
+ Bind(&load_existent);
+ Node* holder = LoadWeakCellValue(maybe_holder_cell);
+ // The |holder| is guaranteed to be alive at this point since we passed
+ // the receiver map check, the validity cell check and the prototype chain
+ // check.
+ CSA_ASSERT(this, WordNotEqual(holder, IntPtrConstant(0)));
+ return holder;
}
void CodeStubAssembler::CheckPrototype(Node* prototype_cell, Node* name,
« no previous file with comments | « src/code-stub-assembler.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698