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

Unified Diff: src/code-stubs.cc

Issue 1894953004: Add HasProperty code stub that tries simple lookups or jumps to runtime otherwise. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebasing Created 4 years, 8 months 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-stubs.h ('k') | src/compiler/js-generic-lowering.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/code-stubs.cc
diff --git a/src/code-stubs.cc b/src/code-stubs.cc
index 4d14e8fdf9b9da58398e9d433820cb5b36ef931a..d01bd7c97bea9987507d042a6b86af7022c4403d 100644
--- a/src/code-stubs.cc
+++ b/src/code-stubs.cc
@@ -4108,6 +4108,123 @@ void TypeofStub::GenerateAheadOfTime(Isolate* isolate) {
stub.GetCode();
}
+void HasPropertyStub::GenerateAssembly(CodeStubAssembler* assembler) const {
+ typedef compiler::Node Node;
+ typedef CodeStubAssembler::Label Label;
+ typedef CodeStubAssembler::Variable Variable;
+
+ Node* key = assembler->Parameter(0);
+ Node* object = assembler->Parameter(1);
+ Node* context = assembler->Parameter(2);
+
+ Label call_runtime(assembler), return_true(assembler),
+ return_false(assembler);
+
+ // Ensure object is JSReceiver, otherwise call runtime to throw error.
+ Label if_objectisnotsmi(assembler);
+ assembler->Branch(assembler->WordIsSmi(object), &call_runtime,
+ &if_objectisnotsmi);
+ assembler->Bind(&if_objectisnotsmi);
+
+ Node* map = assembler->LoadMap(object);
+ Node* instance_type = assembler->LoadMapInstanceType(map);
+ {
+ Label if_objectisreceiver(assembler);
+ STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
+ assembler->Branch(
+ assembler->Int32GreaterThanOrEqual(
+ instance_type, assembler->Int32Constant(FIRST_JS_RECEIVER_TYPE)),
+ &if_objectisreceiver, &call_runtime);
+ assembler->Bind(&if_objectisreceiver);
+ }
+
+ Variable var_index(assembler, MachineRepresentation::kWord32);
+
+ Label keyisindex(assembler), if_iskeyunique(assembler);
+ assembler->TryToName(key, &keyisindex, &var_index, &if_iskeyunique,
+ &call_runtime);
+
+ assembler->Bind(&if_iskeyunique);
+ {
+ Variable var_object(assembler, MachineRepresentation::kTagged);
+ Variable var_map(assembler, MachineRepresentation::kTagged);
+ Variable var_instance_type(assembler, MachineRepresentation::kWord8);
+
+ Variable* merged_variables[] = {&var_object, &var_map, &var_instance_type};
+ Label loop(assembler, arraysize(merged_variables), merged_variables);
+ var_object.Bind(object);
+ var_map.Bind(map);
+ var_instance_type.Bind(instance_type);
+ assembler->Goto(&loop);
+ assembler->Bind(&loop);
+ {
+ Label next_proto(assembler);
+ assembler->TryLookupProperty(var_object.value(), var_map.value(),
+ var_instance_type.value(), key, &return_true,
+ &next_proto, &call_runtime);
+ assembler->Bind(&next_proto);
+
+ Node* proto = assembler->LoadMapPrototype(var_map.value());
+
+ Label if_not_null(assembler);
+ assembler->Branch(assembler->WordEqual(proto, assembler->NullConstant()),
+ &return_false, &if_not_null);
+ assembler->Bind(&if_not_null);
+
+ Node* map = assembler->LoadMap(proto);
+ Node* instance_type = assembler->LoadMapInstanceType(map);
+
+ var_object.Bind(proto);
+ var_map.Bind(map);
+ var_instance_type.Bind(instance_type);
+ assembler->Goto(&loop);
+ }
+ }
+ assembler->Bind(&keyisindex);
+ {
+ Variable var_object(assembler, MachineRepresentation::kTagged);
+ Variable var_map(assembler, MachineRepresentation::kTagged);
+ Variable var_instance_type(assembler, MachineRepresentation::kWord8);
+
+ Variable* merged_variables[] = {&var_object, &var_map, &var_instance_type};
+ Label loop(assembler, arraysize(merged_variables), merged_variables);
+ var_object.Bind(object);
+ var_map.Bind(map);
+ var_instance_type.Bind(instance_type);
+ assembler->Goto(&loop);
+ assembler->Bind(&loop);
+ {
+ Label next_proto(assembler);
+ assembler->TryLookupElement(var_object.value(), var_map.value(),
+ var_instance_type.value(), var_index.value(),
+ &return_true, &next_proto, &call_runtime);
+ assembler->Bind(&next_proto);
+
+ Node* proto = assembler->LoadMapPrototype(var_map.value());
+
+ Label if_not_null(assembler);
+ assembler->Branch(assembler->WordEqual(proto, assembler->NullConstant()),
+ &return_false, &if_not_null);
+ assembler->Bind(&if_not_null);
+
+ Node* map = assembler->LoadMap(proto);
+ Node* instance_type = assembler->LoadMapInstanceType(map);
+
+ var_object.Bind(proto);
+ var_map.Bind(map);
+ var_instance_type.Bind(instance_type);
+ assembler->Goto(&loop);
+ }
+ }
+ assembler->Bind(&return_true);
+ assembler->Return(assembler->BooleanConstant(true));
+
+ assembler->Bind(&return_false);
+ assembler->Return(assembler->BooleanConstant(false));
+
+ assembler->Bind(&call_runtime);
+ assembler->TailCallRuntime(Runtime::kHasProperty, context, key, object);
+}
void CreateAllocationSiteStub::GenerateAheadOfTime(Isolate* isolate) {
CreateAllocationSiteStub stub(isolate);
« no previous file with comments | « src/code-stubs.h ('k') | src/compiler/js-generic-lowering.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698