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

Side by Side Diff: src/ic/accessor-assembler.cc

Issue 2534613002: [ic] Use validity cells to protect keyed element stores against object's prototype chain modificati… (Closed)
Patch Set: Created 4 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
OLDNEW
1 // Copyright 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 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/ic/accessor-assembler.h" 5 #include "src/ic/accessor-assembler.h"
6 #include "src/ic/accessor-assembler-impl.h" 6 #include "src/ic/accessor-assembler-impl.h"
7 7
8 #include "src/code-factory.h" 8 #include "src/code-factory.h"
9 #include "src/code-stubs.h" 9 #include "src/code-stubs.h"
10 #include "src/ic/handler-configuration.h" 10 #include "src/ic/handler-configuration.h"
(...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after
465 Variable var_smi_handler(this, MachineRepresentation::kTagged); 465 Variable var_smi_handler(this, MachineRepresentation::kTagged);
466 Label if_smi_handler(this); 466 Label if_smi_handler(this);
467 HandleLoadICProtoHandlerCase(&p, handler, &var_holder, &var_smi_handler, 467 HandleLoadICProtoHandlerCase(&p, handler, &var_holder, &var_smi_handler,
468 &if_smi_handler, miss, 468 &if_smi_handler, miss,
469 throw_reference_error_if_nonexistent); 469 throw_reference_error_if_nonexistent);
470 Bind(&if_smi_handler); 470 Bind(&if_smi_handler);
471 HandleLoadICSmiHandlerCase(&p, var_holder.value(), var_smi_handler.value(), 471 HandleLoadICSmiHandlerCase(&p, var_holder.value(), var_smi_handler.value(),
472 miss, kOnlyProperties); 472 miss, kOnlyProperties);
473 } 473 }
474 474
475 void AccessorAssemblerImpl::HandleStoreICHandlerCase(const StoreICParameters* p, 475 void AccessorAssemblerImpl::HandleStoreICHandlerCase(
476 Node* handler, 476 const StoreICParameters* p, Node* handler, Label* miss,
477 Label* miss) { 477 ElementSupport support_elements) {
478 Label if_smi_handler(this); 478 Label if_smi_handler(this), if_nonsmi_handler(this);
479 Label try_proto_handler(this), call_handler(this); 479 Label if_proto_handler(this), if_element_handler(this), call_handler(this);
480 480
481 Branch(TaggedIsSmi(handler), &if_smi_handler, &try_proto_handler); 481 Branch(TaggedIsSmi(handler), &if_smi_handler, &if_nonsmi_handler);
482 482
483 // |handler| is a Smi, encoding what to do. See SmiHandler methods 483 // |handler| is a Smi, encoding what to do. See SmiHandler methods
484 // for the encoding format. 484 // for the encoding format.
485 Bind(&if_smi_handler); 485 Bind(&if_smi_handler);
486 { 486 {
487 Node* holder = p->receiver; 487 Node* holder = p->receiver;
488 Node* handler_word = SmiUntag(handler); 488 Node* handler_word = SmiUntag(handler);
489 489
490 // Handle non-transitioning field stores. 490 // Handle non-transitioning field stores.
491 HandleStoreICSmiHandlerCase(handler_word, holder, p->value, nullptr, miss); 491 HandleStoreICSmiHandlerCase(handler_word, holder, p->value, nullptr, miss);
492 } 492 }
493 493
494 Bind(&try_proto_handler); 494 Bind(&if_nonsmi_handler);
495 { 495 {
496 GotoIf(IsCodeMap(LoadMap(handler)), &call_handler); 496 Node* handler_map = LoadMap(handler);
497 if (support_elements == kSupportElements) {
498 GotoIf(IsTuple2Map(handler_map), &if_element_handler);
499 }
500 Branch(IsCodeMap(handler_map), &call_handler, &if_proto_handler);
501 }
502
503 if (support_elements == kSupportElements) {
504 Bind(&if_element_handler);
505 { HandleStoreICElementHandlerCase(p, handler, miss); }
506 }
507
508 Bind(&if_proto_handler);
509 {
497 HandleStoreICProtoHandler(p, handler, miss); 510 HandleStoreICProtoHandler(p, handler, miss);
498 } 511 }
499 512
500 // |handler| is a heap object. Must be code, call it. 513 // |handler| is a heap object. Must be code, call it.
501 Bind(&call_handler); 514 Bind(&call_handler);
502 { 515 {
503 StoreWithVectorDescriptor descriptor(isolate()); 516 StoreWithVectorDescriptor descriptor(isolate());
504 TailCallStub(descriptor, handler, p->context, p->receiver, p->name, 517 TailCallStub(descriptor, handler, p->context, p->receiver, p->name,
505 p->value, p->slot, p->vector); 518 p->value, p->slot, p->vector);
506 } 519 }
507 } 520 }
508 521
522 void AccessorAssemblerImpl::HandleStoreICElementHandlerCase(
523 const StoreICParameters* p, Node* handler, Label* miss) {
524 Comment("HandleStoreICElementHandlerCase");
525 Node* validity_cell = LoadObjectField(handler, Tuple2::kValue1Offset);
526 Node* cell_value = LoadObjectField(validity_cell, Cell::kValueOffset);
527 GotoIf(WordNotEqual(cell_value,
528 SmiConstant(Smi::FromInt(Map::kPrototypeChainValid))),
529 miss);
530
531 Node* code_handler = LoadObjectField(handler, Tuple2::kValue2Offset);
532 CSA_ASSERT(this, IsCodeMap(LoadMap(code_handler)));
533
534 StoreWithVectorDescriptor descriptor(isolate());
535 TailCallStub(descriptor, code_handler, p->context, p->receiver, p->name,
536 p->value, p->slot, p->vector);
537 }
538
509 void AccessorAssemblerImpl::HandleStoreICProtoHandler( 539 void AccessorAssemblerImpl::HandleStoreICProtoHandler(
510 const StoreICParameters* p, Node* handler, Label* miss) { 540 const StoreICParameters* p, Node* handler, Label* miss) {
511 // IC dispatchers rely on these assumptions to be held. 541 // IC dispatchers rely on these assumptions to be held.
512 STATIC_ASSERT(FixedArray::kLengthOffset == 542 STATIC_ASSERT(FixedArray::kLengthOffset ==
513 StoreHandler::kTransitionCellOffset); 543 StoreHandler::kTransitionCellOffset);
514 DCHECK_EQ(FixedArray::OffsetOfElementAt(StoreHandler::kSmiHandlerIndex), 544 DCHECK_EQ(FixedArray::OffsetOfElementAt(StoreHandler::kSmiHandlerIndex),
515 StoreHandler::kSmiHandlerOffset); 545 StoreHandler::kSmiHandlerOffset);
516 DCHECK_EQ(FixedArray::OffsetOfElementAt(StoreHandler::kValidityCellIndex), 546 DCHECK_EQ(FixedArray::OffsetOfElementAt(StoreHandler::kValidityCellIndex),
517 StoreHandler::kValidityCellOffset); 547 StoreHandler::kValidityCellOffset);
518 548
(...skipping 980 matching lines...) Expand 10 before | Expand all | Expand 10 after
1499 1529
1500 Node* receiver_map = LoadReceiverMap(p->receiver); 1530 Node* receiver_map = LoadReceiverMap(p->receiver);
1501 1531
1502 // Check monomorphic case. 1532 // Check monomorphic case.
1503 Node* feedback = 1533 Node* feedback =
1504 TryMonomorphicCase(p->slot, p->vector, receiver_map, &if_handler, 1534 TryMonomorphicCase(p->slot, p->vector, receiver_map, &if_handler,
1505 &var_handler, &try_polymorphic); 1535 &var_handler, &try_polymorphic);
1506 Bind(&if_handler); 1536 Bind(&if_handler);
1507 { 1537 {
1508 Comment("KeyedStoreIC_if_handler"); 1538 Comment("KeyedStoreIC_if_handler");
1509 HandleStoreICHandlerCase(p, var_handler.value(), &miss); 1539 HandleStoreICHandlerCase(p, var_handler.value(), &miss, kSupportElements);
1510 } 1540 }
1511 1541
1512 Bind(&try_polymorphic); 1542 Bind(&try_polymorphic);
1513 { 1543 {
1514 // CheckPolymorphic case. 1544 // CheckPolymorphic case.
1515 Comment("KeyedStoreIC_try_polymorphic"); 1545 Comment("KeyedStoreIC_try_polymorphic");
1516 GotoUnless( 1546 GotoUnless(
1517 WordEqual(LoadMap(feedback), LoadRoot(Heap::kFixedArrayMapRootIndex)), 1547 WordEqual(LoadMap(feedback), LoadRoot(Heap::kFixedArrayMapRootIndex)),
1518 &try_megamorphic); 1548 &try_megamorphic);
1519 Label if_transition_handler(this); 1549 Label if_transition_handler(this);
1520 Variable var_transition_map_cell(this, MachineRepresentation::kTagged); 1550 Variable var_transition_map_cell(this, MachineRepresentation::kTagged);
1521 HandleKeyedStorePolymorphicCase(receiver_map, feedback, &if_handler, 1551 HandleKeyedStorePolymorphicCase(receiver_map, feedback, &if_handler,
1522 &var_handler, &if_transition_handler, 1552 &var_handler, &if_transition_handler,
1523 &var_transition_map_cell, &miss); 1553 &var_transition_map_cell, &miss);
1524 Bind(&if_transition_handler); 1554 Bind(&if_transition_handler);
1525 Comment("KeyedStoreIC_polymorphic_transition"); 1555 Comment("KeyedStoreIC_polymorphic_transition");
1526 Node* transition_map = 1556 {
1527 LoadWeakCellValue(var_transition_map_cell.value(), &miss); 1557 Node* handler = var_handler.value();
1528 StoreTransitionDescriptor descriptor(isolate()); 1558 CSA_ASSERT(this, IsTuple2Map(LoadMap(handler)));
1529 TailCallStub(descriptor, var_handler.value(), p->context, p->receiver, 1559
1530 p->name, transition_map, p->value, p->slot, p->vector); 1560 // Check validity cell.
1561 // HandleStoreICElementHandlerCase(p, handler, miss);
Jakob Kummerow 2016/11/28 18:48:05 leftover?
Igor Sheludko 2016/11/28 22:25:54 Done.
1562
1563 Node* validity_cell = LoadObjectField(handler, Tuple2::kValue1Offset);
1564 Node* cell_value = LoadObjectField(validity_cell, Cell::kValueOffset);
1565 GotoIf(WordNotEqual(cell_value,
1566 SmiConstant(Smi::FromInt(Map::kPrototypeChainValid))),
1567 &miss);
1568
1569 Node* code_handler = LoadObjectField(handler, Tuple2::kValue2Offset);
1570 CSA_ASSERT(this, IsCodeMap(LoadMap(code_handler)));
1571
1572 Node* transition_map =
1573 LoadWeakCellValue(var_transition_map_cell.value(), &miss);
1574 StoreTransitionDescriptor descriptor(isolate());
1575 TailCallStub(descriptor, code_handler, p->context, p->receiver, p->name,
1576 transition_map, p->value, p->slot, p->vector);
1577 }
1531 } 1578 }
1532 1579
1533 Bind(&try_megamorphic); 1580 Bind(&try_megamorphic);
1534 { 1581 {
1535 // Check megamorphic case. 1582 // Check megamorphic case.
1536 Comment("KeyedStoreIC_try_megamorphic"); 1583 Comment("KeyedStoreIC_try_megamorphic");
1537 GotoUnless( 1584 GotoUnless(
1538 WordEqual(feedback, LoadRoot(Heap::kmegamorphic_symbolRootIndex)), 1585 WordEqual(feedback, LoadRoot(Heap::kmegamorphic_symbolRootIndex)),
1539 &try_polymorphic_name); 1586 &try_polymorphic_name);
1540 TailCallStub( 1587 TailCallStub(
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after
1767 void AccessorAssembler::GenerateKeyedStoreICTrampolineTF( 1814 void AccessorAssembler::GenerateKeyedStoreICTrampolineTF(
1768 CodeAssemblerState* state, LanguageMode language_mode) { 1815 CodeAssemblerState* state, LanguageMode language_mode) {
1769 AccessorAssemblerImpl assembler(state); 1816 AccessorAssemblerImpl assembler(state);
1770 assembler.GenerateKeyedStoreICTrampolineTF(language_mode); 1817 assembler.GenerateKeyedStoreICTrampolineTF(language_mode);
1771 } 1818 }
1772 1819
1773 #undef ACCESSOR_ASSEMBLER_PUBLIC_INTERFACE 1820 #undef ACCESSOR_ASSEMBLER_PUBLIC_INTERFACE
1774 1821
1775 } // namespace internal 1822 } // namespace internal
1776 } // namespace v8 1823 } // namespace v8
OLDNEW
« no previous file with comments | « src/factory.cc ('k') | src/ic/accessor-assembler-impl.h » ('j') | src/objects.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698