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

Side by Side Diff: src/objects.cc

Issue 2488223002: [runtime] Ensure Object.freeze() deoptimizes code that depends on global property cells. (Closed)
Patch Set: Created 4 years, 1 month 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 | test/mjsunit/regress/regress-crbug-663750.js » ('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 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 <memory> 9 #include <memory>
10 #include <sstream> 10 #include <sstream>
(...skipping 7967 matching lines...) Expand 10 before | Expand all | Expand 10 after
7978 } 7978 }
7979 if (object->IsJSGlobalProxy()) { 7979 if (object->IsJSGlobalProxy()) {
7980 PrototypeIterator iter(isolate, *object); 7980 PrototypeIterator iter(isolate, *object);
7981 if (iter.IsAtEnd()) return false; 7981 if (iter.IsAtEnd()) return false;
7982 DCHECK(iter.GetCurrent()->IsJSGlobalObject()); 7982 DCHECK(iter.GetCurrent()->IsJSGlobalObject());
7983 return iter.GetCurrent<JSObject>()->map()->is_extensible(); 7983 return iter.GetCurrent<JSObject>()->map()->is_extensible();
7984 } 7984 }
7985 return object->map()->is_extensible(); 7985 return object->map()->is_extensible();
7986 } 7986 }
7987 7987
7988 namespace {
7988 7989
7989 template <typename Dictionary> 7990 template <typename Dictionary>
7990 static void ApplyAttributesToDictionary(Dictionary* dictionary, 7991 void DictionaryDetailsAtPut(Isolate* isolate, Handle<Dictionary> dictionary,
7991 const PropertyAttributes attributes) { 7992 int entry, PropertyDetails details) {
7993 dictionary->DetailsAtPut(entry, details);
7994 }
7995
7996 template <>
7997 void DictionaryDetailsAtPut<GlobalDictionary>(
7998 Isolate* isolate, Handle<GlobalDictionary> dictionary, int entry,
7999 PropertyDetails details) {
8000 Object* value = dictionary->ValueAt(entry);
8001 DCHECK(value->IsPropertyCell());
8002 value = PropertyCell::cast(value)->value();
8003 PropertyCell::PrepareForValue(dictionary, entry, handle(value, isolate),
8004 details);
8005 }
8006
8007 template <typename Dictionary>
8008 void ApplyAttributesToDictionary(Isolate* isolate,
8009 Handle<Dictionary> dictionary,
8010 const PropertyAttributes attributes) {
7992 int capacity = dictionary->Capacity(); 8011 int capacity = dictionary->Capacity();
7993 Isolate* isolate = dictionary->GetIsolate();
7994 for (int i = 0; i < capacity; i++) { 8012 for (int i = 0; i < capacity; i++) {
7995 Object* k = dictionary->KeyAt(i); 8013 Object* k = dictionary->KeyAt(i);
7996 if (dictionary->IsKey(isolate, k) && 8014 if (dictionary->IsKey(isolate, k) &&
7997 !(k->IsSymbol() && Symbol::cast(k)->is_private())) { 8015 !(k->IsSymbol() && Symbol::cast(k)->is_private())) {
7998 PropertyDetails details = dictionary->DetailsAt(i); 8016 PropertyDetails details = dictionary->DetailsAt(i);
7999 int attrs = attributes; 8017 int attrs = attributes;
8000 // READ_ONLY is an invalid attribute for JS setters/getters. 8018 // READ_ONLY is an invalid attribute for JS setters/getters.
8001 if ((attributes & READ_ONLY) && details.type() == ACCESSOR_CONSTANT) { 8019 if ((attributes & READ_ONLY) && details.type() == ACCESSOR_CONSTANT) {
8002 Object* v = dictionary->ValueAt(i); 8020 Object* v = dictionary->ValueAt(i);
8003 if (v->IsPropertyCell()) v = PropertyCell::cast(v)->value(); 8021 if (v->IsPropertyCell()) v = PropertyCell::cast(v)->value();
8004 if (v->IsAccessorPair()) attrs &= ~READ_ONLY; 8022 if (v->IsAccessorPair()) attrs &= ~READ_ONLY;
8005 } 8023 }
8006 details = details.CopyAddAttributes( 8024 details = details.CopyAddAttributes(
8007 static_cast<PropertyAttributes>(attrs)); 8025 static_cast<PropertyAttributes>(attrs));
8008 dictionary->DetailsAtPut(i, details); 8026 DictionaryDetailsAtPut<Dictionary>(isolate, dictionary, i, details);
8009 } 8027 }
8010 } 8028 }
8011 } 8029 }
8012 8030
8031 } // namespace
8013 8032
8014 template <PropertyAttributes attrs> 8033 template <PropertyAttributes attrs>
8015 Maybe<bool> JSObject::PreventExtensionsWithTransition( 8034 Maybe<bool> JSObject::PreventExtensionsWithTransition(
8016 Handle<JSObject> object, ShouldThrow should_throw) { 8035 Handle<JSObject> object, ShouldThrow should_throw) {
8017 STATIC_ASSERT(attrs == NONE || attrs == SEALED || attrs == FROZEN); 8036 STATIC_ASSERT(attrs == NONE || attrs == SEALED || attrs == FROZEN);
8018 8037
8019 // Sealing/freezing sloppy arguments should be handled elsewhere. 8038 // Sealing/freezing sloppy arguments should be handled elsewhere.
8020 DCHECK(!object->HasSloppyArgumentsElements()); 8039 DCHECK(!object->HasSloppyArgumentsElements());
8021 8040
8022 Isolate* isolate = object->GetIsolate(); 8041 Isolate* isolate = object->GetIsolate();
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
8091 ElementsKind new_kind = 8110 ElementsKind new_kind =
8092 IsStringWrapperElementsKind(old_map->elements_kind()) 8111 IsStringWrapperElementsKind(old_map->elements_kind())
8093 ? SLOW_STRING_WRAPPER_ELEMENTS 8112 ? SLOW_STRING_WRAPPER_ELEMENTS
8094 : DICTIONARY_ELEMENTS; 8113 : DICTIONARY_ELEMENTS;
8095 new_map->set_elements_kind(new_kind); 8114 new_map->set_elements_kind(new_kind);
8096 } 8115 }
8097 JSObject::MigrateToMap(object, new_map); 8116 JSObject::MigrateToMap(object, new_map);
8098 8117
8099 if (attrs != NONE) { 8118 if (attrs != NONE) {
8100 if (object->IsJSGlobalObject()) { 8119 if (object->IsJSGlobalObject()) {
8101 ApplyAttributesToDictionary(object->global_dictionary(), attrs); 8120 Handle<GlobalDictionary> dictionary(object->global_dictionary(),
8121 isolate);
8122 ApplyAttributesToDictionary(isolate, dictionary, attrs);
8102 } else { 8123 } else {
8103 ApplyAttributesToDictionary(object->property_dictionary(), attrs); 8124 Handle<NameDictionary> dictionary(object->property_dictionary(),
8125 isolate);
8126 ApplyAttributesToDictionary(isolate, dictionary, attrs);
8104 } 8127 }
8105 } 8128 }
8106 } 8129 }
8107 8130
8108 // Both seal and preventExtensions always go through without modifications to 8131 // Both seal and preventExtensions always go through without modifications to
8109 // typed array elements. Freeze works only if there are no actual elements. 8132 // typed array elements. Freeze works only if there are no actual elements.
8110 if (object->HasFixedTypedArrayElements()) { 8133 if (object->HasFixedTypedArrayElements()) {
8111 if (attrs == FROZEN && 8134 if (attrs == FROZEN &&
8112 JSArrayBufferView::cast(*object)->byte_length()->Number() > 0) { 8135 JSArrayBufferView::cast(*object)->byte_length()->Number() > 0) {
8113 isolate->Throw(*isolate->factory()->NewTypeError( 8136 isolate->Throw(*isolate->factory()->NewTypeError(
8114 MessageTemplate::kCannotFreezeArrayBufferView)); 8137 MessageTemplate::kCannotFreezeArrayBufferView));
8115 return Nothing<bool>(); 8138 return Nothing<bool>();
8116 } 8139 }
8117 return Just(true); 8140 return Just(true);
8118 } 8141 }
8119 8142
8120 DCHECK(object->map()->has_dictionary_elements() || 8143 DCHECK(object->map()->has_dictionary_elements() ||
8121 object->map()->elements_kind() == SLOW_STRING_WRAPPER_ELEMENTS); 8144 object->map()->elements_kind() == SLOW_STRING_WRAPPER_ELEMENTS);
8122 if (!new_element_dictionary.is_null()) { 8145 if (!new_element_dictionary.is_null()) {
8123 object->set_elements(*new_element_dictionary); 8146 object->set_elements(*new_element_dictionary);
8124 } 8147 }
8125 8148
8126 if (object->elements() != isolate->heap()->empty_slow_element_dictionary()) { 8149 if (object->elements() != isolate->heap()->empty_slow_element_dictionary()) {
8127 SeededNumberDictionary* dictionary = object->element_dictionary(); 8150 Handle<SeededNumberDictionary> dictionary(object->element_dictionary(),
8151 isolate);
8128 // Make sure we never go back to the fast case 8152 // Make sure we never go back to the fast case
8129 object->RequireSlowElements(dictionary); 8153 object->RequireSlowElements(*dictionary);
8130 if (attrs != NONE) { 8154 if (attrs != NONE) {
8131 ApplyAttributesToDictionary(dictionary, attrs); 8155 ApplyAttributesToDictionary(isolate, dictionary, attrs);
8132 } 8156 }
8133 } 8157 }
8134 8158
8135 return Just(true); 8159 return Just(true);
8136 } 8160 }
8137 8161
8138 8162
8139 Handle<Object> JSObject::FastPropertyAt(Handle<JSObject> object, 8163 Handle<Object> JSObject::FastPropertyAt(Handle<JSObject> object,
8140 Representation representation, 8164 Representation representation,
8141 FieldIndex index) { 8165 FieldIndex index) {
(...skipping 12167 matching lines...) Expand 10 before | Expand all | Expand 10 after
20309 // Check if the accessor uses a cached property. 20333 // Check if the accessor uses a cached property.
20310 if (!fti->cached_property_name()->IsTheHole(isolate)) { 20334 if (!fti->cached_property_name()->IsTheHole(isolate)) {
20311 return handle(Name::cast(fti->cached_property_name())); 20335 return handle(Name::cast(fti->cached_property_name()));
20312 } 20336 }
20313 } 20337 }
20314 return MaybeHandle<Name>(); 20338 return MaybeHandle<Name>();
20315 } 20339 }
20316 20340
20317 } // namespace internal 20341 } // namespace internal
20318 } // namespace v8 20342 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | test/mjsunit/regress/regress-crbug-663750.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698