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

Side by Side Diff: src/objects.cc

Issue 1500683002: Restructure GetDerivedMap so there's only one place where we read intrinsicDefaultProto (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years 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 | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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/objects.h" 5 #include "src/objects.h"
6 6
7 #include <cmath> 7 #include <cmath>
8 #include <iomanip> 8 #include <iomanip>
9 #include <sstream> 9 #include <sstream>
10 10
(...skipping 12648 matching lines...) Expand 10 before | Expand all | Expand 10 after
12659 12659
12660 // static 12660 // static
12661 MaybeHandle<Map> JSFunction::GetDerivedMap(Isolate* isolate, 12661 MaybeHandle<Map> JSFunction::GetDerivedMap(Isolate* isolate,
12662 Handle<JSFunction> constructor, 12662 Handle<JSFunction> constructor,
12663 Handle<JSReceiver> new_target) { 12663 Handle<JSReceiver> new_target) {
12664 EnsureHasInitialMap(constructor); 12664 EnsureHasInitialMap(constructor);
12665 12665
12666 Handle<Map> constructor_initial_map(constructor->initial_map(), isolate); 12666 Handle<Map> constructor_initial_map(constructor->initial_map(), isolate);
12667 if (*new_target == *constructor) return constructor_initial_map; 12667 if (*new_target == *constructor) return constructor_initial_map;
12668 12668
12669 // Fast case, new.target is a subclass of constructor. The map is cacheable
12670 // (and may already have been cached). new.target.prototype is guaranteed to
12671 // be a JSReceiver.
12672 if (new_target->IsJSFunction()) {
12673 Handle<JSFunction> function = Handle<JSFunction>::cast(new_target);
12674
12675 // Check that |function|'s initial map still in sync with the |constructor|,
12676 // otherwise we must create a new initial map for |function|.
12677 if (function->has_initial_map() &&
12678 function->initial_map()->GetConstructor() == *constructor) {
12679 return handle(function->initial_map(), isolate);
12680 }
12681
12682 // Create a new map with the size and number of in-object properties
12683 // suggested by |function|.
12684
12685 // Link initial map and constructor function if the new.target is actually a
12686 // subclass constructor.
12687 if (IsSubclassConstructor(function->shared()->kind())) {
12688 Handle<Object> prototype(function->instance_prototype(), isolate);
12689 InstanceType instance_type = constructor_initial_map->instance_type();
12690 DCHECK(CanSubclassHaveInobjectProperties(instance_type));
12691 int internal_fields =
12692 JSObject::GetInternalFieldCount(*constructor_initial_map);
12693 int pre_allocated = constructor_initial_map->GetInObjectProperties() -
12694 constructor_initial_map->unused_property_fields();
12695 int instance_size;
12696 int in_object_properties;
12697 function->CalculateInstanceSizeForDerivedClass(
12698 instance_type, internal_fields, &instance_size,
12699 &in_object_properties);
12700
12701 int unused_property_fields = in_object_properties - pre_allocated;
12702 Handle<Map> map =
12703 Map::CopyInitialMap(constructor_initial_map, instance_size,
12704 in_object_properties, unused_property_fields);
12705 map->set_new_target_is_base(false);
12706
12707 JSFunction::SetInitialMap(function, map, prototype);
12708 map->SetConstructor(*constructor);
12709 map->StartInobjectSlackTracking();
12710 return map;
12711 }
12712 }
12713
12714 // Slow path, new.target is either a proxy or can't cache the map.
12715 // new.target.prototype is not guaranteed to be a JSReceiver, and may need to
12716 // fall back to the intrinsicDefaultProto.
12717 Handle<Object> prototype;
12669 if (new_target->IsJSProxy()) { 12718 if (new_target->IsJSProxy()) {
12670 Handle<JSProxy> new_target_proxy = Handle<JSProxy>::cast(new_target); 12719 Handle<JSProxy> new_target_proxy = Handle<JSProxy>::cast(new_target);
12671 Handle<Object> prototype;
12672 Handle<String> prototype_string = isolate->factory()->prototype_string(); 12720 Handle<String> prototype_string = isolate->factory()->prototype_string();
12673 ASSIGN_RETURN_ON_EXCEPTION( 12721 ASSIGN_RETURN_ON_EXCEPTION(
12674 isolate, prototype, 12722 isolate, prototype,
12675 JSReceiver::GetProperty(new_target_proxy, prototype_string), Map); 12723 JSReceiver::GetProperty(new_target_proxy, prototype_string), Map);
12676 Handle<Map> map = Map::CopyInitialMap(constructor_initial_map); 12724 } else {
12677 map->set_new_target_is_base(false); 12725 Handle<JSFunction> function = Handle<JSFunction>::cast(new_target);
12678 12726 // Make sure the new.target.prototype is cached.
12679 if (!prototype->IsJSReceiver()) { 12727 EnsureHasInitialMap(function);
12680 Handle<Context> context; 12728 prototype = handle(function->prototype(), isolate);
12681 ASSIGN_RETURN_ON_EXCEPTION(
12682 isolate, context, JSProxy::GetFunctionRealm(new_target_proxy), Map);
12683 DCHECK(context->IsNativeContext());
12684 // TODO(verwaest): Use the intrinsicDefaultProto instead.
12685 prototype = handle(context->initial_object_prototype(), isolate);
12686 }
12687
12688 if (map->prototype() != *prototype) {
12689 Map::SetPrototype(map, prototype, FAST_PROTOTYPE);
12690 }
12691
12692 map->SetConstructor(*constructor);
12693 return map;
12694 } 12729 }
12695 12730
12696 Handle<JSFunction> new_target_function = Handle<JSFunction>::cast(new_target); 12731 if (!prototype->IsJSReceiver()) {
12697 12732 Handle<Context> context;
12698 // Check that |new_target_function|'s initial map still in sync with 12733 ASSIGN_RETURN_ON_EXCEPTION(isolate, context,
12699 // the |constructor|, otherwise we must create a new initial map for 12734 JSReceiver::GetFunctionRealm(new_target), Map);
12700 // |new_target_function|. 12735 DCHECK(context->IsNativeContext());
12701 if (new_target_function->has_initial_map() && 12736 // TODO(verwaest): Use the intrinsicDefaultProto instead.
12702 new_target_function->initial_map()->GetConstructor() == *constructor) { 12737 prototype = handle(context->initial_object_prototype(), isolate);
12703 return handle(new_target_function->initial_map(), isolate);
12704 }
12705
12706 // Create a new map with the size and number of in-object properties suggested
12707 // by the function.
12708
12709 // Link initial map and constructor function if the original constructor is
12710 // actually a subclass constructor.
12711 if (IsSubclassConstructor(new_target_function->shared()->kind())) {
12712 Handle<Object> prototype(new_target_function->instance_prototype(),
12713 isolate);
12714 InstanceType instance_type = constructor_initial_map->instance_type();
12715 DCHECK(CanSubclassHaveInobjectProperties(instance_type));
12716 int internal_fields =
12717 JSObject::GetInternalFieldCount(*constructor_initial_map);
12718 int pre_allocated = constructor_initial_map->GetInObjectProperties() -
12719 constructor_initial_map->unused_property_fields();
12720 int instance_size;
12721 int in_object_properties;
12722 new_target_function->CalculateInstanceSizeForDerivedClass(
12723 instance_type, internal_fields, &instance_size, &in_object_properties);
12724
12725 int unused_property_fields = in_object_properties - pre_allocated;
12726 Handle<Map> map =
12727 Map::CopyInitialMap(constructor_initial_map, instance_size,
12728 in_object_properties, unused_property_fields);
12729 map->set_new_target_is_base(false);
12730
12731 JSFunction::SetInitialMap(new_target_function, map, prototype);
12732 map->SetConstructor(*constructor);
12733 map->StartInobjectSlackTracking();
12734 return map;
12735 }
12736
12737 // Fetch the prototype.
12738 Handle<Object> prototype;
12739 if (new_target_function->map()->has_non_instance_prototype()) {
12740 // TODO(verwaest): In case of non-instance prototype, use the
12741 // intrinsicDefaultProto instead.
12742 prototype = handle(new_target_function->context()
12743 ->native_context()
12744 ->initial_object_prototype());
12745 } else {
12746 // Make sure the prototype is cached on new_target_function.
12747 EnsureHasInitialMap(new_target_function);
12748 prototype = handle(new_target_function->instance_prototype(), isolate);
12749 } 12738 }
12750 12739
12751 Handle<Map> map = Map::CopyInitialMap(constructor_initial_map); 12740 Handle<Map> map = Map::CopyInitialMap(constructor_initial_map);
12752 map->set_new_target_is_base(false); 12741 map->set_new_target_is_base(false);
12753 DCHECK(prototype->IsJSReceiver()); 12742 DCHECK(prototype->IsJSReceiver());
12754 if (map->prototype() != *prototype) { 12743 if (map->prototype() != *prototype) {
12755 Map::SetPrototype(map, prototype, FAST_PROTOTYPE); 12744 Map::SetPrototype(map, prototype, FAST_PROTOTYPE);
12756 } 12745 }
12757 map->SetConstructor(*constructor); 12746 map->SetConstructor(*constructor);
12758 return map; 12747 return map;
(...skipping 6422 matching lines...) Expand 10 before | Expand all | Expand 10 after
19181 if (cell->value() != *new_value) { 19170 if (cell->value() != *new_value) {
19182 cell->set_value(*new_value); 19171 cell->set_value(*new_value);
19183 Isolate* isolate = cell->GetIsolate(); 19172 Isolate* isolate = cell->GetIsolate();
19184 cell->dependent_code()->DeoptimizeDependentCodeGroup( 19173 cell->dependent_code()->DeoptimizeDependentCodeGroup(
19185 isolate, DependentCode::kPropertyCellChangedGroup); 19174 isolate, DependentCode::kPropertyCellChangedGroup);
19186 } 19175 }
19187 } 19176 }
19188 19177
19189 } // namespace internal 19178 } // namespace internal
19190 } // namespace v8 19179 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698