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

Unified Diff: src/builtins/builtins-object.cc

Issue 2385423005: [stubs] Implement fast TF Builtin for Object.create (Closed)
Patch Set: removing unused symbol Created 4 years, 2 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/builtins/builtins.h ('k') | src/code-stub-assembler.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/builtins/builtins-object.cc
diff --git a/src/builtins/builtins-object.cc b/src/builtins/builtins-object.cc
index b0bb1f043d6686ccccff6e397ddbcdd0327b92fd..6cc2d705b4f556585f60c1793fdfb8207a6d6d13 100644
--- a/src/builtins/builtins-object.cc
+++ b/src/builtins/builtins-object.cc
@@ -459,57 +459,96 @@ void Builtins::Generate_ObjectProtoToString(CodeStubAssembler* assembler) {
}
}
-// ES6 section 19.1.2.2 Object.create ( O [ , Properties ] )
-// TODO(verwaest): Support the common cases with precached map directly in
-// an Object.create stub.
-BUILTIN(ObjectCreate) {
- HandleScope scope(isolate);
- Handle<Object> prototype = args.atOrUndefined(isolate, 1);
- if (!prototype->IsNull(isolate) && !prototype->IsJSReceiver()) {
- THROW_NEW_ERROR_RETURN_FAILURE(
- isolate, NewTypeError(MessageTemplate::kProtoObjectOrNull, prototype));
+void Builtins::Generate_ObjectCreate(CodeStubAssembler* a) {
+ typedef compiler::Node Node;
+ typedef CodeStubAssembler::Label Label;
+ typedef CodeStubAssembler::Variable Variable;
+
+ Node* prototype = a->Parameter(1);
+ Node* properties = a->Parameter(2);
+ Node* context = a->Parameter(3 + 2);
+
+ Label call_runtime(a, Label::kDeferred), prototype_valid(a), no_properties(a);
+ {
+ a->Comment("Argument 1 check: prototype");
+ a->GotoIf(a->WordEqual(prototype, a->NullConstant()), &prototype_valid);
+ a->BranchIfJSReceiver(prototype, &prototype_valid, &call_runtime);
}
- // Generate the map with the specified {prototype} based on the Object
- // function's initial map from the current native context.
- // TODO(bmeurer): Use a dedicated cache for Object.create; think about
- // slack tracking for Object.create.
- Handle<Map> map(isolate->native_context()->object_function()->initial_map(),
- isolate);
- if (map->prototype() != *prototype) {
- if (prototype->IsNull(isolate)) {
- map = isolate->object_with_null_prototype_map();
- } else if (prototype->IsJSObject()) {
- Handle<JSObject> js_prototype = Handle<JSObject>::cast(prototype);
- if (!js_prototype->map()->is_prototype_map()) {
- JSObject::OptimizeAsPrototype(js_prototype, FAST_PROTOTYPE);
- }
- Handle<PrototypeInfo> info =
- Map::GetOrCreatePrototypeInfo(js_prototype, isolate);
- // TODO(verwaest): Use inobject slack tracking for this map.
- if (info->HasObjectCreateMap()) {
- map = handle(info->ObjectCreateMap(), isolate);
- } else {
- map = Map::CopyInitialMap(map);
- Map::SetPrototype(map, prototype, FAST_PROTOTYPE);
- PrototypeInfo::SetObjectCreateMap(info, map);
- }
- } else {
- map = Map::TransitionToPrototype(map, prototype, REGULAR_PROTOTYPE);
- }
+ a->Bind(&prototype_valid);
+ {
+ a->Comment("Argument 2 check: properties");
+ // Check that we have a simple object
+ a->GotoIf(a->TaggedIsSmi(properties), &call_runtime);
+ // Undefined implies no properties.
+ a->GotoIf(a->WordEqual(properties, a->UndefinedConstant()), &no_properties);
+ Node* properties_map = a->LoadMap(properties);
+ a->GotoIf(a->IsSpecialReceiverMap(properties_map), &call_runtime);
+ // Stay on the fast path only if there are no elements.
+ a->GotoUnless(a->WordEqual(a->LoadElements(properties),
+ a->LoadRoot(Heap::kEmptyFixedArrayRootIndex)),
+ &call_runtime);
+ // Jump to the runtime for slow objects.
+ Node* bit_field3 = a->LoadMapBitField3(properties_map);
+ Node* is_fast_map = a->Word32Equal(
+ a->BitFieldDecode<Map::DictionaryMap>(bit_field3), a->Int32Constant(0));
+ a->GotoUnless(is_fast_map, &call_runtime);
+
+ a->Branch(
+ a->WordEqual(
+ a->BitFieldDecodeWord<Map::NumberOfOwnDescriptorsBits>(bit_field3),
+ a->IntPtrConstant(0)),
+ &no_properties, &call_runtime);
}
- // Actually allocate the object.
- Handle<JSObject> object = isolate->factory()->NewJSObjectFromMap(map);
+ // Create a new object with the given prototype.
+ a->Bind(&no_properties);
+ {
+ Variable map(a, MachineRepresentation::kTagged);
+ Label non_null_proto(a), instantiate_map(a), good(a);
+
+ a->Branch(a->WordEqual(prototype, a->NullConstant()), &good,
+ &non_null_proto);
- // Define the properties if properties was specified and is not undefined.
- Handle<Object> properties = args.atOrUndefined(isolate, 2);
- if (!properties->IsUndefined(isolate)) {
- RETURN_FAILURE_ON_EXCEPTION(
- isolate, JSReceiver::DefineProperties(isolate, object, properties));
+ a->Bind(&good);
+ {
+ map.Bind(a->LoadContextElement(context,
+ Context::OBJECT_WITH_NULL_PROTOTYPE_MAP));
+ a->Goto(&instantiate_map);
+ }
+
+ a->Bind(&non_null_proto);
+ {
+ Node* object_function =
+ a->LoadContextElement(context, Context::OBJECT_FUNCTION_INDEX);
+ Node* object_function_map = a->LoadObjectField(
+ object_function, JSFunction::kPrototypeOrInitialMapOffset);
+ map.Bind(object_function_map);
+ a->GotoIf(a->WordEqual(prototype, a->LoadMapPrototype(map.value())),
+ &instantiate_map);
+ // Try loading the prototype info.
+ Node* prototype_info =
+ a->LoadMapPrototypeInfo(a->LoadMap(prototype), &call_runtime);
+ a->Comment("Load ObjectCreateMap from PrototypeInfo");
+ Node* weak_cell =
+ a->LoadObjectField(prototype_info, PrototypeInfo::kObjectCreateMap);
+ a->GotoIf(a->WordEqual(weak_cell, a->UndefinedConstant()), &call_runtime);
+ map.Bind(a->LoadWeakCellValue(weak_cell, &call_runtime));
+ a->Goto(&instantiate_map);
+ }
+
+ a->Bind(&instantiate_map);
+ {
+ Node* instance = a->AllocateJSObjectFromMap(map.value());
+ a->Return(instance);
+ }
}
- return *object;
+ a->Bind(&call_runtime);
+ {
+ a->Return(
+ a->CallRuntime(Runtime::kObjectCreate, context, prototype, properties));
+ }
}
// ES6 section 19.1.2.3 Object.defineProperties
« no previous file with comments | « src/builtins/builtins.h ('k') | src/code-stub-assembler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698