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

Side by Side Diff: src/ast/ast.cc

Issue 2445333002: Ensure slow properties for simple {__proto__:null} literals. (Closed)
Patch Set: fixing typo Created 3 years, 9 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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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/ast/ast.h" 5 #include "src/ast/ast.h"
6 6
7 #include <cmath> // For isfinite. 7 #include <cmath> // For isfinite.
8 8
9 #include "src/ast/compile-time-value.h" 9 #include "src/ast/compile-time-value.h"
10 #include "src/ast/prettyprinter.h" 10 #include "src/ast/prettyprinter.h"
(...skipping 477 matching lines...) Expand 10 before | Expand all | Expand 10 after
488 property->SetSlot(spec->AddStoreICSlot(language_mode)); 488 property->SetSlot(spec->AddStoreICSlot(language_mode));
489 } 489 }
490 break; 490 break;
491 } 491 }
492 } 492 }
493 493
494 for (; property_index < properties()->length(); property_index++) { 494 for (; property_index < properties()->length(); property_index++) {
495 ObjectLiteral::Property* property = properties()->at(property_index); 495 ObjectLiteral::Property* property = properties()->at(property_index);
496 496
497 Expression* value = property->value(); 497 Expression* value = property->value();
498 if (property->kind() != ObjectLiteral::Property::PROTOTYPE) { 498 if (!property->IsPrototype()) {
499 if (FunctionLiteral::NeedsHomeObject(value)) { 499 if (FunctionLiteral::NeedsHomeObject(value)) {
500 property->SetSlot(spec->AddStoreICSlot(language_mode)); 500 property->SetSlot(spec->AddStoreICSlot(language_mode));
501 } 501 }
502 } 502 }
503 property->SetStoreDataPropertySlot( 503 property->SetStoreDataPropertySlot(
504 spec->AddStoreDataPropertyInLiteralICSlot()); 504 spec->AddStoreDataPropertyInLiteralICSlot());
505 } 505 }
506 } 506 }
507 507
508 508
509 void ObjectLiteral::CalculateEmitStore(Zone* zone) { 509 void ObjectLiteral::CalculateEmitStore(Zone* zone) {
510 const auto GETTER = ObjectLiteral::Property::GETTER; 510 const auto GETTER = ObjectLiteral::Property::GETTER;
511 const auto SETTER = ObjectLiteral::Property::SETTER; 511 const auto SETTER = ObjectLiteral::Property::SETTER;
512 512
513 ZoneAllocationPolicy allocator(zone); 513 ZoneAllocationPolicy allocator(zone);
514 514
515 CustomMatcherZoneHashMap table( 515 CustomMatcherZoneHashMap table(
516 Literal::Match, ZoneHashMap::kDefaultHashMapCapacity, allocator); 516 Literal::Match, ZoneHashMap::kDefaultHashMapCapacity, allocator);
517 for (int i = properties()->length() - 1; i >= 0; i--) { 517 for (int i = properties()->length() - 1; i >= 0; i--) {
518 ObjectLiteral::Property* property = properties()->at(i); 518 ObjectLiteral::Property* property = properties()->at(i);
519 if (property->is_computed_name()) continue; 519 if (property->is_computed_name()) continue;
520 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) continue; 520 if (property->IsPrototype()) continue;
521 Literal* literal = property->key()->AsLiteral(); 521 Literal* literal = property->key()->AsLiteral();
522 DCHECK(!literal->IsNullLiteral()); 522 DCHECK(!literal->IsNullLiteral());
523 523
524 // If there is an existing entry do not emit a store unless the previous 524 // If there is an existing entry do not emit a store unless the previous
525 // entry was also an accessor. 525 // entry was also an accessor.
526 uint32_t hash = literal->Hash(); 526 uint32_t hash = literal->Hash();
527 ZoneHashMap::Entry* entry = table.LookupOrInsert(literal, hash, allocator); 527 ZoneHashMap::Entry* entry = table.LookupOrInsert(literal, hash, allocator);
528 if (entry->value != NULL) { 528 if (entry->value != NULL) {
529 auto previous_kind = 529 auto previous_kind =
530 static_cast<ObjectLiteral::Property*>(entry->value)->kind(); 530 static_cast<ObjectLiteral::Property*>(entry->value)->kind();
531 if (!((property->kind() == GETTER && previous_kind == SETTER) || 531 if (!((property->kind() == GETTER && previous_kind == SETTER) ||
532 (property->kind() == SETTER && previous_kind == GETTER))) { 532 (property->kind() == SETTER && previous_kind == GETTER))) {
533 property->set_emit_store(false); 533 property->set_emit_store(false);
534 } 534 }
535 } 535 }
536 entry->value = property; 536 entry->value = property;
537 } 537 }
538 } 538 }
539 539
540 540
541 bool ObjectLiteral::IsBoilerplateProperty(ObjectLiteral::Property* property) { 541 bool ObjectLiteral::IsBoilerplateProperty(ObjectLiteral::Property* property) {
542 return property != NULL && 542 return property != NULL && !property->IsPrototype();
543 property->kind() != ObjectLiteral::Property::PROTOTYPE;
544 } 543 }
545 544
546 void ObjectLiteral::InitDepthAndFlags() { 545 void ObjectLiteral::InitDepthAndFlags() {
547 if (depth_ > 0) return; 546 if (depth_ > 0) return;
548 547 uint32_t position = 0;
549 int position = 0;
550 // Accumulate the value in local variables and store it at the end. 548 // Accumulate the value in local variables and store it at the end.
551 bool is_simple = true; 549 bool is_simple = true;
552 int depth_acc = 1; 550 int depth_acc = 1;
553 uint32_t max_element_index = 0; 551 uint32_t max_element_index = 0;
554 uint32_t elements = 0; 552 uint32_t elements = 0;
555 for (int i = 0; i < properties()->length(); i++) { 553 for (int i = 0; i < properties()->length(); i++) {
556 ObjectLiteral::Property* property = properties()->at(i); 554 ObjectLiteral::Property* property = properties()->at(i);
557 if (!IsBoilerplateProperty(property)) { 555 if (!IsBoilerplateProperty(property)) {
Toon Verwaest 2017/03/20 14:47:11 This is actually just property->IsPrototype(). The
Camillo Bruni 2017/04/26 11:54:46 done.
556 // __proto__:null has no side-effects and is set directly on the
557 // boilerplate.
558 if (property->IsNullPrototype()) {
559 set_has_null_protoype(true);
560 continue;
561 }
562 DCHECK(!has_null_prototype());
558 is_simple = false; 563 is_simple = false;
559 continue; 564 continue;
560 } 565 }
561 566 // Only check for __proto__:null after the first computed property name.
562 if (static_cast<uint32_t>(position) == boilerplate_properties_ * 2) { 567 if (position > boilerplate_properties_) {
Toon Verwaest 2017/03/20 14:47:11 What about simply doing a loop: if (position == b
Camillo Bruni 2017/04/26 11:54:46 Added separate helper method. I will still iterate
568 continue;
569 } else if (position == boilerplate_properties_) {
563 DCHECK(property->is_computed_name()); 570 DCHECK(property->is_computed_name());
564 is_simple = false; 571 is_simple = false;
565 break; 572 position++;
573 continue;
566 } 574 }
567 DCHECK(!property->is_computed_name()); 575 DCHECK(!property->is_computed_name());
568 576
569 MaterializedLiteral* m_literal = property->value()->AsMaterializedLiteral(); 577 MaterializedLiteral* m_literal = property->value()->AsMaterializedLiteral();
570 if (m_literal != NULL) { 578 if (m_literal != NULL) {
571 m_literal->InitDepthAndFlags(); 579 m_literal->InitDepthAndFlags();
572 if (m_literal->depth() >= depth_acc) depth_acc = m_literal->depth() + 1; 580 if (m_literal->depth() >= depth_acc) depth_acc = m_literal->depth() + 1;
573 } 581 }
574 582
575 const AstValue* key = property->key()->AsLiteral()->raw_value(); 583 const AstValue* key = property->key()->AsLiteral()->raw_value();
(...skipping 18 matching lines...) Expand all
594 // literal with fast elements will be a waste of space. 602 // literal with fast elements will be a waste of space.
595 uint32_t element_index = 0; 603 uint32_t element_index = 0;
596 if (key->IsString() && key->AsString()->AsArrayIndex(&element_index)) { 604 if (key->IsString() && key->AsString()->AsArrayIndex(&element_index)) {
597 max_element_index = Max(element_index, max_element_index); 605 max_element_index = Max(element_index, max_element_index);
598 elements++; 606 elements++;
599 } else if (key->ToUint32(&element_index) && element_index != kMaxUInt32) { 607 } else if (key->ToUint32(&element_index) && element_index != kMaxUInt32) {
600 max_element_index = Max(element_index, max_element_index); 608 max_element_index = Max(element_index, max_element_index);
601 elements++; 609 elements++;
602 } 610 }
603 611
604 // Increment the position for the key and the value. 612 position++;
605 position += 2;
606 } 613 }
607 614
608 bit_field_ = FastElementsField::update( 615 set_fast_elements((max_element_index <= 32) ||
609 bit_field_, 616 ((2 * elements) >= max_element_index));
610 (max_element_index <= 32) || ((2 * elements) >= max_element_index)); 617 set_has_elements(elements > 0);
611 bit_field_ = HasElementsField::update(bit_field_, elements > 0); 618 bit_field_ = HasElementsField::update(bit_field_, elements > 0);
Toon Verwaest 2017/03/20 14:47:11 Leftover code?
Camillo Bruni 2017/04/26 11:54:46 removed.
612 619
613 set_is_simple(is_simple); 620 set_is_simple(is_simple);
614 set_depth(depth_acc); 621 set_depth(depth_acc);
615 } 622 }
616 623
617 void ObjectLiteral::BuildConstantProperties(Isolate* isolate) { 624 void ObjectLiteral::BuildConstantProperties(Isolate* isolate) {
618 if (!constant_properties_.is_null()) return; 625 if (!constant_properties_.is_null()) return;
619 626
620 int index_keys = 0; 627 int index_keys = 0;
621 bool has_seen_proto = false; 628 bool has_seen_proto = false;
(...skipping 494 matching lines...) Expand 10 before | Expand all | Expand 10 after
1116 #ifdef DEBUG 1123 #ifdef DEBUG
1117 return is_jsruntime() ? NameForNativeContextIntrinsicIndex(context_index_) 1124 return is_jsruntime() ? NameForNativeContextIntrinsicIndex(context_index_)
1118 : function_->name; 1125 : function_->name;
1119 #else 1126 #else
1120 return is_jsruntime() ? "(context function)" : function_->name; 1127 return is_jsruntime() ? "(context function)" : function_->name;
1121 #endif // DEBUG 1128 #endif // DEBUG
1122 } 1129 }
1123 1130
1124 } // namespace internal 1131 } // namespace internal
1125 } // namespace v8 1132 } // namespace v8
OLDNEW
« no previous file with comments | « src/ast/ast.h ('k') | src/bootstrapper.cc » ('j') | src/builtins/builtins-constructor-gen.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698