Index: src/code-stub-assembler.cc |
diff --git a/src/code-stub-assembler.cc b/src/code-stub-assembler.cc |
index be6bf6e2001f1779548aafd923fe26d288f7a483..34b480705c0fe2633d5c5fc5457b650ec4986e5d 100644 |
--- a/src/code-stub-assembler.cc |
+++ b/src/code-stub-assembler.cc |
@@ -507,6 +507,11 @@ Node* CodeStubAssembler::LoadInstanceType(Node* object) { |
return LoadMapInstanceType(LoadMap(object)); |
} |
+void CodeStubAssembler::AssertInstanceType(Node* object, |
+ InstanceType instance_type) { |
+ Assert(Word32Equal(LoadInstanceType(object), Int32Constant(instance_type))); |
+} |
+ |
Node* CodeStubAssembler::LoadProperties(Node* object) { |
return LoadObjectField(object, JSObject::kPropertiesOffset); |
} |
@@ -570,8 +575,12 @@ Node* CodeStubAssembler::LoadJSValueValue(Node* object) { |
return LoadObjectField(object, JSValue::kValueOffset); |
} |
-Node* CodeStubAssembler::LoadWeakCellValue(Node* weak_cell) { |
- return LoadObjectField(weak_cell, WeakCell::kValueOffset); |
+Node* CodeStubAssembler::LoadWeakCellValue(Node* weak_cell, Label* if_cleared) { |
+ Node* value = LoadObjectField(weak_cell, WeakCell::kValueOffset); |
+ if (if_cleared != nullptr) { |
+ GotoIf(WordEqual(value, IntPtrConstant(0)), if_cleared); |
+ } |
+ return value; |
} |
Node* CodeStubAssembler::AllocateUninitializedFixedArray(Node* length) { |
@@ -1828,7 +1837,7 @@ void CodeStubAssembler::TryLookupElement(Node* object, Node* map, |
} |
Bind(&if_isfaststringwrapper); |
{ |
- Assert(Word32Equal(LoadInstanceType(object), Int32Constant(JS_VALUE_TYPE))); |
+ AssertInstanceType(object, JS_VALUE_TYPE); |
Node* string = LoadJSValueValue(object); |
Assert(Int32LessThan(LoadInstanceType(string), |
Int32Constant(FIRST_NONSTRING_TYPE))); |
@@ -1838,7 +1847,7 @@ void CodeStubAssembler::TryLookupElement(Node* object, Node* map, |
} |
Bind(&if_isslowstringwrapper); |
{ |
- Assert(Word32Equal(LoadInstanceType(object), Int32Constant(JS_VALUE_TYPE))); |
+ AssertInstanceType(object, JS_VALUE_TYPE); |
Node* string = LoadJSValueValue(object); |
Assert(Int32LessThan(LoadInstanceType(string), |
Int32Constant(FIRST_NONSTRING_TYPE))); |
@@ -2265,11 +2274,12 @@ void CodeStubAssembler::TryProbeStubCache( |
} |
} |
-void CodeStubAssembler::LoadIC(const LoadICParameters* p, Label* if_miss) { |
+void CodeStubAssembler::LoadIC(const LoadICParameters* p) { |
Variable var_handler(this, MachineRepresentation::kTagged); |
// TODO(ishell): defer blocks when it works. |
Label if_handler(this, &var_handler), try_polymorphic(this), |
- try_megamorphic(this /*, Label::kDeferred*/); |
+ try_megamorphic(this /*, Label::kDeferred*/), |
+ miss(this /*, Label::kDeferred*/); |
Node* receiver_map = LoadReceiverMap(p->receiver); |
@@ -2290,7 +2300,7 @@ void CodeStubAssembler::LoadIC(const LoadICParameters* p, Label* if_miss) { |
WordEqual(LoadMap(feedback), LoadRoot(Heap::kFixedArrayMapRootIndex)), |
&try_megamorphic); |
HandlePolymorphicCase(p, receiver_map, feedback, &if_handler, &var_handler, |
- if_miss, 2); |
+ &miss, 2); |
} |
Bind(&try_megamorphic); |
@@ -2298,13 +2308,55 @@ void CodeStubAssembler::LoadIC(const LoadICParameters* p, Label* if_miss) { |
// Check megamorphic case. |
GotoUnless( |
WordEqual(feedback, LoadRoot(Heap::kmegamorphic_symbolRootIndex)), |
- if_miss); |
+ &miss); |
Code::Flags code_flags = |
Code::RemoveHolderFromFlags(Code::ComputeHandlerFlags(Code::LOAD_IC)); |
TryProbeStubCache(isolate()->stub_cache(), code_flags, p->receiver, p->name, |
- &if_handler, &var_handler, if_miss); |
+ &if_handler, &var_handler, &miss); |
+ } |
+ Bind(&miss); |
+ { |
+ TailCallRuntime(Runtime::kLoadIC_Miss, p->context, p->receiver, p->name, |
+ p->slot, p->vector); |
+ } |
+} |
+ |
+void CodeStubAssembler::LoadGlobalIC(const LoadICParameters* p) { |
+ Label try_handler(this), miss(this); |
+ Node* weak_cell = |
+ LoadFixedArrayElement(p->vector, p->slot, 0, SMI_PARAMETERS); |
+ AssertInstanceType(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); |
+ AssertInstanceType(property_cell, PROPERTY_CELL_TYPE); |
+ |
+ Node* value = LoadObjectField(property_cell, PropertyCell::kValueOffset); |
+ GotoIf(WordEqual(value, TheHoleConstant()), &miss); |
+ Return(value); |
+ |
+ Bind(&try_handler); |
+ { |
+ Node* handler = |
+ LoadFixedArrayElement(p->vector, p->slot, kPointerSize, SMI_PARAMETERS); |
+ GotoIf(WordEqual(handler, LoadRoot(Heap::kuninitialized_symbolRootIndex)), |
+ &miss); |
+ |
+ // In this case {handler} must be a Code object. |
+ AssertInstanceType(handler, CODE_TYPE); |
+ LoadWithVectorDescriptor descriptor(isolate()); |
+ Node* native_context = LoadNativeContext(p->context); |
+ Node* receiver = LoadFixedArrayElement( |
+ native_context, Int32Constant(Context::EXTENSION_INDEX)); |
+ TailCallStub(descriptor, handler, p->context, receiver, p->name, p->slot, |
+ p->vector); |
+ } |
+ Bind(&miss); |
+ { |
+ TailCallRuntime(Runtime::kLoadGlobalIC_Miss, p->context, p->name, p->slot, |
+ p->vector); |
} |
} |