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

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
Igor Sheludko 2015/12/03 16:40:40 Please reformat.
12684 // by |function|.
12685
12686 // Link initial map and constructor function if the new.target is actually a
12687 // subclass constructor.
12688 if (IsSubclassConstructor(function->shared()->kind())) {
12689 Handle<Object> prototype(function->instance_prototype(), isolate);
12690 InstanceType instance_type = constructor_initial_map->instance_type();
12691 DCHECK(CanSubclassHaveInobjectProperties(instance_type));
12692 int internal_fields =
12693 JSObject::GetInternalFieldCount(*constructor_initial_map);
12694 int pre_allocated = constructor_initial_map->GetInObjectProperties() -
12695 constructor_initial_map->unused_property_fields();
12696 int instance_size;
12697 int in_object_properties;
12698 function->CalculateInstanceSizeForDerivedClass(
12699 instance_type, internal_fields, &instance_size,
12700 &in_object_properties);
12701
12702 int unused_property_fields = in_object_properties - pre_allocated;
12703 Handle<Map> map =
12704 Map::CopyInitialMap(constructor_initial_map, instance_size,
12705 in_object_properties, unused_property_fields);
12706 map->set_new_target_is_base(false);
12707
12708 JSFunction::SetInitialMap(function, map, prototype);
12709 map->SetConstructor(*constructor);
12710 map->StartInobjectSlackTracking();
12711 return map;
12712 }
12713 }
12714
12715 // Slow path, new.target is either a proxy or can't cache the map.
12716 // new.target.prototype is not guaranteed to be a JSReceiver, and may need to
12717 // fall back to the intrinsicDefaultProto.
12718 Handle<Object> prototype;
12669 if (new_target->IsJSProxy()) { 12719 if (new_target->IsJSProxy()) {
12670 Handle<JSProxy> new_target_proxy = Handle<JSProxy>::cast(new_target); 12720 Handle<JSProxy> new_target_proxy = Handle<JSProxy>::cast(new_target);
12671 Handle<Object> prototype;
12672 Handle<String> prototype_string = isolate->factory()->prototype_string(); 12721 Handle<String> prototype_string = isolate->factory()->prototype_string();
12673 ASSIGN_RETURN_ON_EXCEPTION( 12722 ASSIGN_RETURN_ON_EXCEPTION(
12674 isolate, prototype, 12723 isolate, prototype,
12675 JSReceiver::GetProperty(new_target_proxy, prototype_string), Map); 12724 JSReceiver::GetProperty(new_target_proxy, prototype_string), Map);
12676 Handle<Map> map = Map::CopyInitialMap(constructor_initial_map); 12725 } else {
12677 map->set_new_target_is_base(false); 12726 Handle<JSFunction> function = Handle<JSFunction>::cast(new_target);
12678 12727 // Make sure the new.target.prototype is cached.
12679 if (!prototype->IsJSReceiver()) { 12728 EnsureHasInitialMap(function);
12680 Handle<Context> context; 12729 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 } 12730 }
12695 12731
12696 Handle<JSFunction> new_target_function = Handle<JSFunction>::cast(new_target); 12732 if (!prototype->IsJSReceiver()) {
12697 12733 Handle<Context> context;
12698 // Check that |new_target_function|'s initial map still in sync with 12734 ASSIGN_RETURN_ON_EXCEPTION(isolate, context,
12699 // the |constructor|, otherwise we must create a new initial map for 12735 JSReceiver::GetFunctionRealm(new_target), Map);
12700 // |new_target_function|. 12736 DCHECK(context->IsNativeContext());
12701 if (new_target_function->has_initial_map() && 12737 // TODO(verwaest): Use the intrinsicDefaultProto instead.
12702 new_target_function->initial_map()->GetConstructor() == *constructor) { 12738 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 } 12739 }
12750 12740
12751 Handle<Map> map = Map::CopyInitialMap(constructor_initial_map); 12741 Handle<Map> map = Map::CopyInitialMap(constructor_initial_map);
12752 map->set_new_target_is_base(false); 12742 map->set_new_target_is_base(false);
12753 DCHECK(prototype->IsJSReceiver()); 12743 DCHECK(prototype->IsJSReceiver());
12754 if (map->prototype() != *prototype) { 12744 if (map->prototype() != *prototype) {
12755 Map::SetPrototype(map, prototype, FAST_PROTOTYPE); 12745 Map::SetPrototype(map, prototype, FAST_PROTOTYPE);
12756 } 12746 }
12757 map->SetConstructor(*constructor); 12747 map->SetConstructor(*constructor);
12758 return map; 12748 return map;
(...skipping 6422 matching lines...) Expand 10 before | Expand all | Expand 10 after
19181 if (cell->value() != *new_value) { 19171 if (cell->value() != *new_value) {
19182 cell->set_value(*new_value); 19172 cell->set_value(*new_value);
19183 Isolate* isolate = cell->GetIsolate(); 19173 Isolate* isolate = cell->GetIsolate();
19184 cell->dependent_code()->DeoptimizeDependentCodeGroup( 19174 cell->dependent_code()->DeoptimizeDependentCodeGroup(
19185 isolate, DependentCode::kPropertyCellChangedGroup); 19175 isolate, DependentCode::kPropertyCellChangedGroup);
19186 } 19176 }
19187 } 19177 }
19188 19178
19189 } // namespace internal 19179 } // namespace internal
19190 } // namespace v8 19180 } // 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