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

Side by Side Diff: src/objects.cc

Issue 2915863004: [runtime] PreventExtensionsWithTransition: before adding the new (Closed)
Patch Set: [runtime] fix memory leak in PreventExtensionsWithTransition Created 3 years, 6 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/objects.h ('k') | test/mjsunit/harmony/private.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 7403 matching lines...) Expand 10 before | Expand all | Expand 10 after
7414 } 7414 }
7415 7415
7416 7416
7417 Maybe<bool> JSReceiver::SetIntegrityLevel(Handle<JSReceiver> receiver, 7417 Maybe<bool> JSReceiver::SetIntegrityLevel(Handle<JSReceiver> receiver,
7418 IntegrityLevel level, 7418 IntegrityLevel level,
7419 ShouldThrow should_throw) { 7419 ShouldThrow should_throw) {
7420 DCHECK(level == SEALED || level == FROZEN); 7420 DCHECK(level == SEALED || level == FROZEN);
7421 7421
7422 if (receiver->IsJSObject()) { 7422 if (receiver->IsJSObject()) {
7423 Handle<JSObject> object = Handle<JSObject>::cast(receiver); 7423 Handle<JSObject> object = Handle<JSObject>::cast(receiver);
7424
7424 if (!object->HasSloppyArgumentsElements()) { // Fast path. 7425 if (!object->HasSloppyArgumentsElements()) { // Fast path.
7426 // prevent memory leaks by not adding unnecessary transitions
7427 Maybe<bool> test = JSObject::TestIntegrityLevel(object, level);
7428 MAYBE_RETURN(test, Nothing<bool>());
7429 if (test.FromJust()) return test;
7430
7425 if (level == SEALED) { 7431 if (level == SEALED) {
7426 return JSObject::PreventExtensionsWithTransition<SEALED>(object, 7432 return JSObject::PreventExtensionsWithTransition<SEALED>(object,
7427 should_throw); 7433 should_throw);
7428 } else { 7434 } else {
7429 return JSObject::PreventExtensionsWithTransition<FROZEN>(object, 7435 return JSObject::PreventExtensionsWithTransition<FROZEN>(object,
7430 should_throw); 7436 should_throw);
7431 } 7437 }
7432 } 7438 }
7433 } 7439 }
7434 7440
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
7470 ? no_conf 7476 ? no_conf
7471 : no_conf_no_write; 7477 : no_conf_no_write;
7472 MAYBE_RETURN( 7478 MAYBE_RETURN(
7473 DefineOwnProperty(isolate, receiver, key, &desc, THROW_ON_ERROR), 7479 DefineOwnProperty(isolate, receiver, key, &desc, THROW_ON_ERROR),
7474 Nothing<bool>()); 7480 Nothing<bool>());
7475 } 7481 }
7476 } 7482 }
7477 return Just(true); 7483 return Just(true);
7478 } 7484 }
7479 7485
7486 namespace {
7480 7487
7481 Maybe<bool> JSReceiver::TestIntegrityLevel(Handle<JSReceiver> object, 7488 template <typename Dictionary>
7482 IntegrityLevel level) { 7489 bool TestDictionaryPropertiesIntegrityLevel(Dictionary dict, Isolate* isolate,
7490 PropertyAttributes level) {
7483 DCHECK(level == SEALED || level == FROZEN); 7491 DCHECK(level == SEALED || level == FROZEN);
7484 Isolate* isolate = object->GetIsolate();
7485 7492
7486 Maybe<bool> extensible = JSReceiver::IsExtensible(object); 7493 uint32_t capacity = dict->Capacity();
7494 for (uint32_t i = 0; i < capacity; i++) {
7495 Object* key = dict->KeyAt(i);
7496 if (!dict->IsKey(isolate, key) || key->FilterKey(ALL_PROPERTIES) ||
7497 dict->IsDeleted(i))
7498 continue;
7499 PropertyDetails details = dict->DetailsAt(i);
7500 if (details.IsConfigurable()) return false;
7501 if (level == FROZEN && details.kind() == kData && !details.IsReadOnly()) {
7502 return false;
7503 }
7504 }
7505 return true;
7506 }
7507
7508 bool TestFastPropertiesIntegrityLevel(Map* map, PropertyAttributes level) {
7509 DCHECK(level == SEALED || level == FROZEN);
7510 DCHECK_LT(LAST_CUSTOM_ELEMENTS_RECEIVER, map->instance_type());
7511 DCHECK(!map->is_dictionary_map());
7512
7513 DescriptorArray* descriptors = map->instance_descriptors();
7514 int number_of_own_descriptors = map->NumberOfOwnDescriptors();
7515 for (int i = 0; i < number_of_own_descriptors; i++) {
7516 if (descriptors->GetKey(i)->IsPrivate()) continue;
7517 PropertyDetails details = descriptors->GetDetails(i);
7518 if (details.IsConfigurable()) return false;
7519 if (level == FROZEN && details.kind() == kData && !details.IsReadOnly()) {
7520 return false;
7521 }
7522 }
7523 return true;
7524 }
7525
7526 bool TestPropertiesIntegrityLevel(JSObject* object, PropertyAttributes level) {
7527 DCHECK_LT(LAST_CUSTOM_ELEMENTS_RECEIVER, object->map()->instance_type());
7528
7529 if (object->HasFastProperties()) {
7530 return TestFastPropertiesIntegrityLevel(object->map(), level);
7531 }
7532
7533 return TestDictionaryPropertiesIntegrityLevel(object->property_dictionary(),
7534 object->GetIsolate(), level);
7535 }
7536
7537 bool TestElementsIntegrityLevel(JSObject* object, PropertyAttributes level) {
7538 DCHECK(!object->HasSloppyArgumentsElements());
7539
7540 ElementsKind kind = object->GetElementsKind();
7541
7542 if (IsDictionaryElementsKind(kind)) {
7543 return TestDictionaryPropertiesIntegrityLevel(
7544 SeededNumberDictionary::cast(object->elements()), object->GetIsolate(),
7545 level);
7546 }
7547
7548 ElementsAccessor* accessor = ElementsAccessor::ForKind(kind);
7549 // Only DICTIONARY_ELEMENTS and SLOW_SLOPPY_ARGUMENTS_ELEMENTS have
7550 // PropertyAttributes so just test if empty
7551 return accessor->NumberOfElements(object) == 0;
7552 }
7553
7554 bool FastTestIntegrityLevel(JSObject* object, PropertyAttributes level) {
7555 DCHECK_LT(LAST_CUSTOM_ELEMENTS_RECEIVER, object->map()->instance_type());
7556
7557 return !object->map()->is_extensible() &&
7558 TestElementsIntegrityLevel(object, level) &&
7559 TestPropertiesIntegrityLevel(object, level);
7560 }
7561
7562 Maybe<bool> GenericTestIntegrityLevel(Handle<JSReceiver> receiver,
7563 PropertyAttributes level) {
7564 DCHECK(level == SEALED || level == FROZEN);
7565
7566 Maybe<bool> extensible = JSReceiver::IsExtensible(receiver);
7487 MAYBE_RETURN(extensible, Nothing<bool>()); 7567 MAYBE_RETURN(extensible, Nothing<bool>());
7488 if (extensible.FromJust()) return Just(false); 7568 if (extensible.FromJust()) return Just(false);
7489 7569
7570 Isolate* isolate = receiver->GetIsolate();
7571
7490 Handle<FixedArray> keys; 7572 Handle<FixedArray> keys;
7491 ASSIGN_RETURN_ON_EXCEPTION_VALUE( 7573 ASSIGN_RETURN_ON_EXCEPTION_VALUE(
7492 isolate, keys, JSReceiver::OwnPropertyKeys(object), Nothing<bool>()); 7574 isolate, keys, JSReceiver::OwnPropertyKeys(receiver), Nothing<bool>());
7493 7575
7494 for (int i = 0; i < keys->length(); ++i) { 7576 for (int i = 0; i < keys->length(); ++i) {
7495 Handle<Object> key(keys->get(i), isolate); 7577 Handle<Object> key(keys->get(i), isolate);
7496 PropertyDescriptor current_desc; 7578 PropertyDescriptor current_desc;
7497 Maybe<bool> owned = JSReceiver::GetOwnPropertyDescriptor( 7579 Maybe<bool> owned = JSReceiver::GetOwnPropertyDescriptor(
7498 isolate, object, key, &current_desc); 7580 isolate, receiver, key, &current_desc);
7499 MAYBE_RETURN(owned, Nothing<bool>()); 7581 MAYBE_RETURN(owned, Nothing<bool>());
7500 if (owned.FromJust()) { 7582 if (owned.FromJust()) {
7501 if (current_desc.configurable()) return Just(false); 7583 if (current_desc.configurable()) return Just(false);
7502 if (level == FROZEN && 7584 if (level == FROZEN &&
7503 PropertyDescriptor::IsDataDescriptor(&current_desc) && 7585 PropertyDescriptor::IsDataDescriptor(&current_desc) &&
7504 current_desc.writable()) { 7586 current_desc.writable()) {
7505 return Just(false); 7587 return Just(false);
7506 } 7588 }
7507 } 7589 }
7508 } 7590 }
7509 return Just(true); 7591 return Just(true);
7510 } 7592 }
7511 7593
7594 } // namespace
7595
7596 Maybe<bool> JSReceiver::TestIntegrityLevel(Handle<JSReceiver> receiver,
7597 IntegrityLevel level) {
7598 if (receiver->map()->instance_type() > LAST_CUSTOM_ELEMENTS_RECEIVER) {
7599 return JSObject::TestIntegrityLevel(Handle<JSObject>::cast(receiver),
7600 level);
7601 }
7602 return GenericTestIntegrityLevel(receiver, level);
7603 }
7604
7605 Maybe<bool> JSObject::TestIntegrityLevel(Handle<JSObject> object,
7606 IntegrityLevel level) {
7607 if (object->map()->instance_type() > LAST_CUSTOM_ELEMENTS_RECEIVER &&
7608 !object->HasSloppyArgumentsElements()) {
7609 return Just(FastTestIntegrityLevel(*object, level));
7610 }
7611 return GenericTestIntegrityLevel(Handle<JSReceiver>::cast(object), level);
7612 }
7512 7613
7513 Maybe<bool> JSReceiver::PreventExtensions(Handle<JSReceiver> object, 7614 Maybe<bool> JSReceiver::PreventExtensions(Handle<JSReceiver> object,
7514 ShouldThrow should_throw) { 7615 ShouldThrow should_throw) {
7515 if (object->IsJSProxy()) { 7616 if (object->IsJSProxy()) {
7516 return JSProxy::PreventExtensions(Handle<JSProxy>::cast(object), 7617 return JSProxy::PreventExtensions(Handle<JSProxy>::cast(object),
7517 should_throw); 7618 should_throw);
7518 } 7619 }
7519 DCHECK(object->IsJSObject()); 7620 DCHECK(object->IsJSObject());
7520 return JSObject::PreventExtensions(Handle<JSObject>::cast(object), 7621 return JSObject::PreventExtensions(Handle<JSObject>::cast(object),
7521 should_throw); 7622 should_throw);
(...skipping 12651 matching lines...) Expand 10 before | Expand all | Expand 10 after
20173 // not 20274 // not
20174 // depend on this. 20275 // depend on this.
20175 return DICTIONARY_ELEMENTS; 20276 return DICTIONARY_ELEMENTS;
20176 } 20277 }
20177 DCHECK_LE(kind, LAST_ELEMENTS_KIND); 20278 DCHECK_LE(kind, LAST_ELEMENTS_KIND);
20178 return kind; 20279 return kind;
20179 } 20280 }
20180 } 20281 }
20181 } // namespace internal 20282 } // namespace internal
20182 } // namespace v8 20283 } // namespace v8
OLDNEW
« no previous file with comments | « src/objects.h ('k') | test/mjsunit/harmony/private.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698