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

Side by Side 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 unified diff | Download patch
« no previous file with comments | « src/builtins/builtins.h ('k') | src/code-stub-assembler.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/builtins/builtins.h" 5 #include "src/builtins/builtins.h"
6 #include "src/builtins/builtins-utils.h" 6 #include "src/builtins/builtins-utils.h"
7 7
8 #include "src/code-factory.h" 8 #include "src/code-factory.h"
9 #include "src/property-descriptor.h" 9 #include "src/property-descriptor.h"
10 10
(...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after
452 &return_object, &return_function); 452 &return_object, &return_function);
453 } 453 }
454 454
455 // Default 455 // Default
456 assembler->Bind(&return_object); 456 assembler->Bind(&return_object);
457 assembler->Return(assembler->HeapConstant( 457 assembler->Return(assembler->HeapConstant(
458 assembler->isolate()->factory()->object_to_string())); 458 assembler->isolate()->factory()->object_to_string()));
459 } 459 }
460 } 460 }
461 461
462 // ES6 section 19.1.2.2 Object.create ( O [ , Properties ] ) 462 void Builtins::Generate_ObjectCreate(CodeStubAssembler* a) {
463 // TODO(verwaest): Support the common cases with precached map directly in 463 typedef compiler::Node Node;
464 // an Object.create stub. 464 typedef CodeStubAssembler::Label Label;
465 BUILTIN(ObjectCreate) { 465 typedef CodeStubAssembler::Variable Variable;
466 HandleScope scope(isolate); 466
467 Handle<Object> prototype = args.atOrUndefined(isolate, 1); 467 Node* prototype = a->Parameter(1);
468 if (!prototype->IsNull(isolate) && !prototype->IsJSReceiver()) { 468 Node* properties = a->Parameter(2);
469 THROW_NEW_ERROR_RETURN_FAILURE( 469 Node* context = a->Parameter(3 + 2);
470 isolate, NewTypeError(MessageTemplate::kProtoObjectOrNull, prototype)); 470
471 Label call_runtime(a, Label::kDeferred), prototype_valid(a), no_properties(a);
472 {
473 a->Comment("Argument 1 check: prototype");
474 a->GotoIf(a->WordEqual(prototype, a->NullConstant()), &prototype_valid);
475 a->BranchIfJSReceiver(prototype, &prototype_valid, &call_runtime);
471 } 476 }
472 477
473 // Generate the map with the specified {prototype} based on the Object 478 a->Bind(&prototype_valid);
474 // function's initial map from the current native context. 479 {
475 // TODO(bmeurer): Use a dedicated cache for Object.create; think about 480 a->Comment("Argument 2 check: properties");
476 // slack tracking for Object.create. 481 // Check that we have a simple object
477 Handle<Map> map(isolate->native_context()->object_function()->initial_map(), 482 a->GotoIf(a->TaggedIsSmi(properties), &call_runtime);
478 isolate); 483 // Undefined implies no properties.
479 if (map->prototype() != *prototype) { 484 a->GotoIf(a->WordEqual(properties, a->UndefinedConstant()), &no_properties);
480 if (prototype->IsNull(isolate)) { 485 Node* properties_map = a->LoadMap(properties);
481 map = isolate->object_with_null_prototype_map(); 486 a->GotoIf(a->IsSpecialReceiverMap(properties_map), &call_runtime);
482 } else if (prototype->IsJSObject()) { 487 // Stay on the fast path only if there are no elements.
483 Handle<JSObject> js_prototype = Handle<JSObject>::cast(prototype); 488 a->GotoUnless(a->WordEqual(a->LoadElements(properties),
484 if (!js_prototype->map()->is_prototype_map()) { 489 a->LoadRoot(Heap::kEmptyFixedArrayRootIndex)),
485 JSObject::OptimizeAsPrototype(js_prototype, FAST_PROTOTYPE); 490 &call_runtime);
486 } 491 // Jump to the runtime for slow objects.
487 Handle<PrototypeInfo> info = 492 Node* bit_field3 = a->LoadMapBitField3(properties_map);
488 Map::GetOrCreatePrototypeInfo(js_prototype, isolate); 493 Node* is_fast_map = a->Word32Equal(
489 // TODO(verwaest): Use inobject slack tracking for this map. 494 a->BitFieldDecode<Map::DictionaryMap>(bit_field3), a->Int32Constant(0));
490 if (info->HasObjectCreateMap()) { 495 a->GotoUnless(is_fast_map, &call_runtime);
491 map = handle(info->ObjectCreateMap(), isolate); 496
492 } else { 497 a->Branch(
493 map = Map::CopyInitialMap(map); 498 a->WordEqual(
494 Map::SetPrototype(map, prototype, FAST_PROTOTYPE); 499 a->BitFieldDecodeWord<Map::NumberOfOwnDescriptorsBits>(bit_field3),
495 PrototypeInfo::SetObjectCreateMap(info, map); 500 a->IntPtrConstant(0)),
496 } 501 &no_properties, &call_runtime);
497 } else { 502 }
498 map = Map::TransitionToPrototype(map, prototype, REGULAR_PROTOTYPE); 503
504 // Create a new object with the given prototype.
505 a->Bind(&no_properties);
506 {
507 Variable map(a, MachineRepresentation::kTagged);
508 Label non_null_proto(a), instantiate_map(a), good(a);
509
510 a->Branch(a->WordEqual(prototype, a->NullConstant()), &good,
511 &non_null_proto);
512
513 a->Bind(&good);
514 {
515 map.Bind(a->LoadContextElement(context,
516 Context::OBJECT_WITH_NULL_PROTOTYPE_MAP));
517 a->Goto(&instantiate_map);
518 }
519
520 a->Bind(&non_null_proto);
521 {
522 Node* object_function =
523 a->LoadContextElement(context, Context::OBJECT_FUNCTION_INDEX);
524 Node* object_function_map = a->LoadObjectField(
525 object_function, JSFunction::kPrototypeOrInitialMapOffset);
526 map.Bind(object_function_map);
527 a->GotoIf(a->WordEqual(prototype, a->LoadMapPrototype(map.value())),
528 &instantiate_map);
529 // Try loading the prototype info.
530 Node* prototype_info =
531 a->LoadMapPrototypeInfo(a->LoadMap(prototype), &call_runtime);
532 a->Comment("Load ObjectCreateMap from PrototypeInfo");
533 Node* weak_cell =
534 a->LoadObjectField(prototype_info, PrototypeInfo::kObjectCreateMap);
535 a->GotoIf(a->WordEqual(weak_cell, a->UndefinedConstant()), &call_runtime);
536 map.Bind(a->LoadWeakCellValue(weak_cell, &call_runtime));
537 a->Goto(&instantiate_map);
538 }
539
540 a->Bind(&instantiate_map);
541 {
542 Node* instance = a->AllocateJSObjectFromMap(map.value());
543 a->Return(instance);
499 } 544 }
500 } 545 }
501 546
502 // Actually allocate the object. 547 a->Bind(&call_runtime);
503 Handle<JSObject> object = isolate->factory()->NewJSObjectFromMap(map); 548 {
504 549 a->Return(
505 // Define the properties if properties was specified and is not undefined. 550 a->CallRuntime(Runtime::kObjectCreate, context, prototype, properties));
506 Handle<Object> properties = args.atOrUndefined(isolate, 2);
507 if (!properties->IsUndefined(isolate)) {
508 RETURN_FAILURE_ON_EXCEPTION(
509 isolate, JSReceiver::DefineProperties(isolate, object, properties));
510 } 551 }
511
512 return *object;
513 } 552 }
514 553
515 // ES6 section 19.1.2.3 Object.defineProperties 554 // ES6 section 19.1.2.3 Object.defineProperties
516 BUILTIN(ObjectDefineProperties) { 555 BUILTIN(ObjectDefineProperties) {
517 HandleScope scope(isolate); 556 HandleScope scope(isolate);
518 DCHECK_EQ(3, args.length()); 557 DCHECK_EQ(3, args.length());
519 Handle<Object> target = args.at<Object>(1); 558 Handle<Object> target = args.at<Object>(1);
520 Handle<Object> properties = args.at<Object>(2); 559 Handle<Object> properties = args.at<Object>(2);
521 560
522 RETURN_RESULT_OR_FAILURE( 561 RETURN_RESULT_OR_FAILURE(
(...skipping 490 matching lines...) Expand 10 before | Expand all | Expand 10 after
1013 typedef CompareDescriptor Descriptor; 1052 typedef CompareDescriptor Descriptor;
1014 Node* object = assembler->Parameter(Descriptor::kLeft); 1053 Node* object = assembler->Parameter(Descriptor::kLeft);
1015 Node* callable = assembler->Parameter(Descriptor::kRight); 1054 Node* callable = assembler->Parameter(Descriptor::kRight);
1016 Node* context = assembler->Parameter(Descriptor::kContext); 1055 Node* context = assembler->Parameter(Descriptor::kContext);
1017 1056
1018 assembler->Return(assembler->InstanceOf(object, callable, context)); 1057 assembler->Return(assembler->InstanceOf(object, callable, context));
1019 } 1058 }
1020 1059
1021 } // namespace internal 1060 } // namespace internal
1022 } // namespace v8 1061 } // namespace v8
OLDNEW
« 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