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

Side by Side Diff: src/objects.cc

Issue 2108203002: Implement immutable prototype chains (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: simplify Created 4 years, 5 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
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 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 8663 matching lines...) Expand 10 before | Expand all | Expand 10 after
8674 result->set_migration_target(false); 8674 result->set_migration_target(false);
8675 result->set_construction_counter(kNoSlackTracking); 8675 result->set_construction_counter(kNoSlackTracking);
8676 8676
8677 #ifdef VERIFY_HEAP 8677 #ifdef VERIFY_HEAP
8678 if (FLAG_verify_heap) result->DictionaryMapVerify(); 8678 if (FLAG_verify_heap) result->DictionaryMapVerify();
8679 #endif 8679 #endif
8680 8680
8681 return result; 8681 return result;
8682 } 8682 }
8683 8683
8684 // Return an immutable prototype exotic object version of the input map.
8685 // This is not cached in the transition tree because it is only used on
Toon Verwaest 2016/06/30 15:35:33 The comment is a little inaccurate. The JS_GLOBAL_
Dan Ehrenberg 2016/06/30 23:12:41 Changed the comment; WDYT?
8686 // the global object, and excluding it saves memory on the map transition
8687 // tree.
8688
8689 // static
8690 Handle<Map> Map::TransitionToImmutableProto(Handle<Map> map) {
8691 Handle<Map> new_map = Map::Copy(map, "ImmutablePrototype");
8692 new_map->set_immutable_proto(true);
8693 return new_map;
8694 }
8684 8695
8685 Handle<Map> Map::CopyInitialMap(Handle<Map> map, int instance_size, 8696 Handle<Map> Map::CopyInitialMap(Handle<Map> map, int instance_size,
8686 int in_object_properties, 8697 int in_object_properties,
8687 int unused_property_fields) { 8698 int unused_property_fields) {
8688 #ifdef DEBUG 8699 #ifdef DEBUG
8689 Isolate* isolate = map->GetIsolate(); 8700 Isolate* isolate = map->GetIsolate();
8690 // Strict function maps have Function as a constructor but the 8701 // Strict function maps have Function as a constructor but the
8691 // Function's initial map is a sloppy function map. Same holds for 8702 // Function's initial map is a sloppy function map. Same holds for
8692 // GeneratorFunction and its initial map. 8703 // GeneratorFunction and its initial map.
8693 Object* constructor = map->GetConstructor(); 8704 Object* constructor = map->GetConstructor();
(...skipping 6272 matching lines...) Expand 10 before | Expand all | Expand 10 after
14966 real_receiver = PrototypeIterator::GetCurrent<JSObject>(iter); 14977 real_receiver = PrototypeIterator::GetCurrent<JSObject>(iter);
14967 iter.Advance(); 14978 iter.Advance();
14968 all_extensible = all_extensible && real_receiver->map()->is_extensible(); 14979 all_extensible = all_extensible && real_receiver->map()->is_extensible();
14969 } 14980 }
14970 } 14981 }
14971 Handle<Map> map(real_receiver->map()); 14982 Handle<Map> map(real_receiver->map());
14972 14983
14973 // Nothing to do if prototype is already set. 14984 // Nothing to do if prototype is already set.
14974 if (map->prototype() == *value) return Just(true); 14985 if (map->prototype() == *value) return Just(true);
14975 14986
14987 bool immutable_proto = object->map()->is_immutable_proto();
14988 if (immutable_proto) {
14989 RETURN_FAILURE(
14990 isolate, should_throw,
14991 NewTypeError(MessageTemplate::kImmutablePrototypeSet, object));
14992 }
14993
14976 // From 8.6.2 Object Internal Methods 14994 // From 8.6.2 Object Internal Methods
14977 // ... 14995 // ...
14978 // In addition, if [[Extensible]] is false the value of the [[Class]] and 14996 // In addition, if [[Extensible]] is false the value of the [[Class]] and
14979 // [[Prototype]] internal properties of the object may not be modified. 14997 // [[Prototype]] internal properties of the object may not be modified.
14980 // ... 14998 // ...
14981 // Implementation specific extensions that modify [[Class]], [[Prototype]] 14999 // Implementation specific extensions that modify [[Class]], [[Prototype]]
14982 // or [[Extensible]] must not violate the invariants defined in the preceding 15000 // or [[Extensible]] must not violate the invariants defined in the preceding
14983 // paragraph. 15001 // paragraph.
14984 if (!all_extensible) { 15002 if (!all_extensible) {
14985 RETURN_FAILURE(isolate, should_throw, 15003 RETURN_FAILURE(isolate, should_throw,
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
15017 // KeyedStoreICs need to be cleared to ensure any that involve this 15035 // KeyedStoreICs need to be cleared to ensure any that involve this
15018 // map go generic. 15036 // map go generic.
15019 TypeFeedbackVector::ClearAllKeyedStoreICs(isolate); 15037 TypeFeedbackVector::ClearAllKeyedStoreICs(isolate);
15020 } 15038 }
15021 15039
15022 heap->ClearInstanceofCache(); 15040 heap->ClearInstanceofCache();
15023 DCHECK(size == object->Size()); 15041 DCHECK(size == object->Size());
15024 return Just(true); 15042 return Just(true);
15025 } 15043 }
15026 15044
15045 // static
15046 Maybe<bool> JSObject::SetImmutableProto(Handle<JSObject> object,
15047 bool from_javascript,
15048 ShouldThrow should_throw) {
15049 Isolate* isolate = object->GetIsolate();
15050
15051 if (from_javascript) {
Toon Verwaest 2016/06/30 15:35:33 I guess this shouldn't be possible? So shouldn't b
Dan Ehrenberg 2016/06/30 23:12:41 Good point, nicer to not have that code. I include
15052 if (object->IsAccessCheckNeeded() &&
15053 !isolate->MayAccess(handle(isolate->context()), object)) {
15054 isolate->ReportFailedAccessCheck(object);
15055 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
15056 RETURN_FAILURE(isolate, should_throw,
15057 NewTypeError(MessageTemplate::kNoAccess));
15058 }
15059 } else {
15060 DCHECK(!object->IsAccessCheckNeeded());
15061 }
15062
15063 Handle<JSObject> real_receiver = object;
15064 if (from_javascript) {
15065 // Find the first object in the chain whose prototype object is not
15066 // hidden.
15067 PrototypeIterator iter(isolate, real_receiver, kStartAtPrototype,
15068 PrototypeIterator::END_AT_NON_HIDDEN);
15069 while (!iter.IsAtEnd()) {
15070 // Casting to JSObject is fine because hidden prototypes are never
15071 // JSProxies.
15072 real_receiver = PrototypeIterator::GetCurrent<JSObject>(iter);
15073 iter.Advance();
15074 }
15075 }
15076 Handle<Map> map(real_receiver->map());
15077
15078 // Nothing to do if prototype is already set.
15079 if (map->is_immutable_proto()) return Just(true);
15080 Handle<Map> new_map = Map::TransitionToImmutableProto(map);
15081 object->set_map(*new_map);
15082 return Just(true);
15083 }
15027 15084
15028 void JSObject::EnsureCanContainElements(Handle<JSObject> object, 15085 void JSObject::EnsureCanContainElements(Handle<JSObject> object,
15029 Arguments* args, 15086 Arguments* args,
15030 uint32_t first_arg, 15087 uint32_t first_arg,
15031 uint32_t arg_count, 15088 uint32_t arg_count,
15032 EnsureElementsMode mode) { 15089 EnsureElementsMode mode) {
15033 // Elements in |Arguments| are ordered backwards (because they're on the 15090 // Elements in |Arguments| are ordered backwards (because they're on the
15034 // stack), but the method that's called here iterates over them in forward 15091 // stack), but the method that's called here iterates over them in forward
15035 // direction. 15092 // direction.
15036 return EnsureCanContainElements( 15093 return EnsureCanContainElements(
(...skipping 3962 matching lines...) Expand 10 before | Expand all | Expand 10 after
18999 19056
19000 Object* data_obj = 19057 Object* data_obj =
19001 constructor->shared()->get_api_func_data()->access_check_info(); 19058 constructor->shared()->get_api_func_data()->access_check_info();
19002 if (data_obj->IsUndefined(isolate)) return nullptr; 19059 if (data_obj->IsUndefined(isolate)) return nullptr;
19003 19060
19004 return AccessCheckInfo::cast(data_obj); 19061 return AccessCheckInfo::cast(data_obj);
19005 } 19062 }
19006 19063
19007 } // namespace internal 19064 } // namespace internal
19008 } // namespace v8 19065 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698