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

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: The fix 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
« no previous file with comments | « src/factory.cc ('k') | src/ic/accessor-assembler-impl.h » ('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 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 452 matching lines...) Expand 10 before | Expand all | Expand 10 after
463 Variable var_smi_handler(this, MachineRepresentation::kTagged); 463 Variable var_smi_handler(this, MachineRepresentation::kTagged);
464 Label if_smi_handler(this); 464 Label if_smi_handler(this);
465 HandleLoadICProtoHandlerCase(&p, handler, &var_holder, &var_smi_handler, 465 HandleLoadICProtoHandlerCase(&p, handler, &var_holder, &var_smi_handler,
466 &if_smi_handler, miss, 466 &if_smi_handler, miss,
467 throw_reference_error_if_nonexistent); 467 throw_reference_error_if_nonexistent);
468 Bind(&if_smi_handler); 468 Bind(&if_smi_handler);
469 HandleLoadICSmiHandlerCase(&p, var_holder.value(), var_smi_handler.value(), 469 HandleLoadICSmiHandlerCase(&p, var_holder.value(), var_smi_handler.value(),
470 miss, kOnlyProperties); 470 miss, kOnlyProperties);
471 } 471 }
472 472
473 void AccessorAssemblerImpl::HandleStoreICHandlerCase(const StoreICParameters* p, 473 void AccessorAssemblerImpl::HandleStoreICHandlerCase(
474 Node* handler, 474 const StoreICParameters* p, Node* handler, Label* miss,
475 Label* miss) { 475 ElementSupport support_elements) {
476 Label if_smi_handler(this); 476 Label if_smi_handler(this), if_nonsmi_handler(this);
477 Label try_proto_handler(this), call_handler(this); 477 Label if_proto_handler(this), if_element_handler(this), call_handler(this);
478 478
479 Branch(TaggedIsSmi(handler), &if_smi_handler, &try_proto_handler); 479 Branch(TaggedIsSmi(handler), &if_smi_handler, &if_nonsmi_handler);
480 480
481 // |handler| is a Smi, encoding what to do. See SmiHandler methods 481 // |handler| is a Smi, encoding what to do. See SmiHandler methods
482 // for the encoding format. 482 // for the encoding format.
483 Bind(&if_smi_handler); 483 Bind(&if_smi_handler);
484 { 484 {
485 Node* holder = p->receiver; 485 Node* holder = p->receiver;
486 Node* handler_word = SmiUntag(handler); 486 Node* handler_word = SmiUntag(handler);
487 487
488 // Handle non-transitioning field stores. 488 // Handle non-transitioning field stores.
489 HandleStoreICSmiHandlerCase(handler_word, holder, p->value, nullptr, miss); 489 HandleStoreICSmiHandlerCase(handler_word, holder, p->value, nullptr, miss);
490 } 490 }
491 491
492 Bind(&try_proto_handler); 492 Bind(&if_nonsmi_handler);
493 { 493 {
494 GotoIf(IsCodeMap(LoadMap(handler)), &call_handler); 494 Node* handler_map = LoadMap(handler);
495 if (support_elements == kSupportElements) {
496 GotoIf(IsTuple2Map(handler_map), &if_element_handler);
497 }
498 Branch(IsCodeMap(handler_map), &call_handler, &if_proto_handler);
Igor Sheludko 2016/12/02 09:32:36 StoreIC still supports code handlers if IsTuple2()
499 }
500
501 if (support_elements == kSupportElements) {
502 Bind(&if_element_handler);
503 { HandleStoreICElementHandlerCase(p, handler, miss); }
504 }
505
506 Bind(&if_proto_handler);
507 {
495 HandleStoreICProtoHandler(p, handler, miss); 508 HandleStoreICProtoHandler(p, handler, miss);
496 } 509 }
497 510
498 // |handler| is a heap object. Must be code, call it. 511 // |handler| is a heap object. Must be code, call it.
499 Bind(&call_handler); 512 Bind(&call_handler);
500 { 513 {
501 StoreWithVectorDescriptor descriptor(isolate()); 514 StoreWithVectorDescriptor descriptor(isolate());
502 TailCallStub(descriptor, handler, p->context, p->receiver, p->name, 515 TailCallStub(descriptor, handler, p->context, p->receiver, p->name,
503 p->value, p->slot, p->vector); 516 p->value, p->slot, p->vector);
504 } 517 }
505 } 518 }
506 519
520 void AccessorAssemblerImpl::HandleStoreICElementHandlerCase(
521 const StoreICParameters* p, Node* handler, Label* miss) {
522 Comment("HandleStoreICElementHandlerCase");
523 Node* validity_cell = LoadObjectField(handler, Tuple2::kValue1Offset);
524 Node* cell_value = LoadObjectField(validity_cell, Cell::kValueOffset);
525 GotoIf(WordNotEqual(cell_value,
526 SmiConstant(Smi::FromInt(Map::kPrototypeChainValid))),
527 miss);
528
529 Node* code_handler = LoadObjectField(handler, Tuple2::kValue2Offset);
530 CSA_ASSERT(this, IsCodeMap(LoadMap(code_handler)));
531
532 StoreWithVectorDescriptor descriptor(isolate());
533 TailCallStub(descriptor, code_handler, p->context, p->receiver, p->name,
534 p->value, p->slot, p->vector);
535 }
536
507 void AccessorAssemblerImpl::HandleStoreICProtoHandler( 537 void AccessorAssemblerImpl::HandleStoreICProtoHandler(
508 const StoreICParameters* p, Node* handler, Label* miss) { 538 const StoreICParameters* p, Node* handler, Label* miss) {
509 // IC dispatchers rely on these assumptions to be held. 539 // IC dispatchers rely on these assumptions to be held.
510 STATIC_ASSERT(FixedArray::kLengthOffset == 540 STATIC_ASSERT(FixedArray::kLengthOffset ==
511 StoreHandler::kTransitionCellOffset); 541 StoreHandler::kTransitionCellOffset);
512 DCHECK_EQ(FixedArray::OffsetOfElementAt(StoreHandler::kSmiHandlerIndex), 542 DCHECK_EQ(FixedArray::OffsetOfElementAt(StoreHandler::kSmiHandlerIndex),
513 StoreHandler::kSmiHandlerOffset); 543 StoreHandler::kSmiHandlerOffset);
514 DCHECK_EQ(FixedArray::OffsetOfElementAt(StoreHandler::kValidityCellIndex), 544 DCHECK_EQ(FixedArray::OffsetOfElementAt(StoreHandler::kValidityCellIndex),
515 StoreHandler::kValidityCellOffset); 545 StoreHandler::kValidityCellOffset);
516 546
(...skipping 979 matching lines...) Expand 10 before | Expand all | Expand 10 after
1496 1526
1497 Node* receiver_map = LoadReceiverMap(p->receiver); 1527 Node* receiver_map = LoadReceiverMap(p->receiver);
1498 1528
1499 // Check monomorphic case. 1529 // Check monomorphic case.
1500 Node* feedback = 1530 Node* feedback =
1501 TryMonomorphicCase(p->slot, p->vector, receiver_map, &if_handler, 1531 TryMonomorphicCase(p->slot, p->vector, receiver_map, &if_handler,
1502 &var_handler, &try_polymorphic); 1532 &var_handler, &try_polymorphic);
1503 Bind(&if_handler); 1533 Bind(&if_handler);
1504 { 1534 {
1505 Comment("KeyedStoreIC_if_handler"); 1535 Comment("KeyedStoreIC_if_handler");
1506 HandleStoreICHandlerCase(p, var_handler.value(), &miss); 1536 HandleStoreICHandlerCase(p, var_handler.value(), &miss, kSupportElements);
1507 } 1537 }
1508 1538
1509 Bind(&try_polymorphic); 1539 Bind(&try_polymorphic);
1510 { 1540 {
1511 // CheckPolymorphic case. 1541 // CheckPolymorphic case.
1512 Comment("KeyedStoreIC_try_polymorphic"); 1542 Comment("KeyedStoreIC_try_polymorphic");
1513 GotoUnless( 1543 GotoUnless(
1514 WordEqual(LoadMap(feedback), LoadRoot(Heap::kFixedArrayMapRootIndex)), 1544 WordEqual(LoadMap(feedback), LoadRoot(Heap::kFixedArrayMapRootIndex)),
1515 &try_megamorphic); 1545 &try_megamorphic);
1516 Label if_transition_handler(this); 1546 Label if_transition_handler(this);
1517 Variable var_transition_map_cell(this, MachineRepresentation::kTagged); 1547 Variable var_transition_map_cell(this, MachineRepresentation::kTagged);
1518 HandleKeyedStorePolymorphicCase(receiver_map, feedback, &if_handler, 1548 HandleKeyedStorePolymorphicCase(receiver_map, feedback, &if_handler,
1519 &var_handler, &if_transition_handler, 1549 &var_handler, &if_transition_handler,
1520 &var_transition_map_cell, &miss); 1550 &var_transition_map_cell, &miss);
1521 Bind(&if_transition_handler); 1551 Bind(&if_transition_handler);
1522 Comment("KeyedStoreIC_polymorphic_transition"); 1552 Comment("KeyedStoreIC_polymorphic_transition");
1523 Node* transition_map = 1553 {
1524 LoadWeakCellValue(var_transition_map_cell.value(), &miss); 1554 Node* handler = var_handler.value();
1525 StoreTransitionDescriptor descriptor(isolate()); 1555
1526 TailCallStub(descriptor, var_handler.value(), p->context, p->receiver, 1556 Label call_handler(this);
1527 p->name, transition_map, p->value, p->slot, p->vector); 1557 Variable var_code_handler(this, MachineRepresentation::kTagged);
1558 var_code_handler.Bind(handler);
1559 GotoUnless(IsTuple2Map(LoadMap(handler)), &call_handler);
1560 {
1561 CSA_ASSERT(this, IsTuple2Map(LoadMap(handler)));
1562
1563 // Check validity cell.
1564 Node* validity_cell = LoadObjectField(handler, Tuple2::kValue1Offset);
1565 Node* cell_value = LoadObjectField(validity_cell, Cell::kValueOffset);
1566 GotoIf(WordNotEqual(cell_value, SmiConstant(Map::kPrototypeChainValid)),
1567 &miss);
1568
1569 var_code_handler.Bind(LoadObjectField(handler, Tuple2::kValue2Offset));
1570 Goto(&call_handler);
1571 }
1572
1573 Bind(&call_handler);
1574 {
1575 Node* code_handler = var_code_handler.value();
1576 CSA_ASSERT(this, IsCodeMap(LoadMap(code_handler)));
1577
1578 Node* transition_map =
1579 LoadWeakCellValue(var_transition_map_cell.value(), &miss);
1580 StoreTransitionDescriptor descriptor(isolate());
1581 TailCallStub(descriptor, code_handler, p->context, p->receiver, p->name,
1582 transition_map, p->value, p->slot, p->vector);
1583 }
1584 }
1528 } 1585 }
1529 1586
1530 Bind(&try_megamorphic); 1587 Bind(&try_megamorphic);
1531 { 1588 {
1532 // Check megamorphic case. 1589 // Check megamorphic case.
1533 Comment("KeyedStoreIC_try_megamorphic"); 1590 Comment("KeyedStoreIC_try_megamorphic");
1534 GotoUnless( 1591 GotoUnless(
1535 WordEqual(feedback, LoadRoot(Heap::kmegamorphic_symbolRootIndex)), 1592 WordEqual(feedback, LoadRoot(Heap::kmegamorphic_symbolRootIndex)),
1536 &try_polymorphic_name); 1593 &try_polymorphic_name);
1537 TailCallStub( 1594 TailCallStub(
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after
1764 void AccessorAssembler::GenerateKeyedStoreICTrampolineTF( 1821 void AccessorAssembler::GenerateKeyedStoreICTrampolineTF(
1765 CodeAssemblerState* state, LanguageMode language_mode) { 1822 CodeAssemblerState* state, LanguageMode language_mode) {
1766 AccessorAssemblerImpl assembler(state); 1823 AccessorAssemblerImpl assembler(state);
1767 assembler.GenerateKeyedStoreICTrampolineTF(language_mode); 1824 assembler.GenerateKeyedStoreICTrampolineTF(language_mode);
1768 } 1825 }
1769 1826
1770 #undef ACCESSOR_ASSEMBLER_PUBLIC_INTERFACE 1827 #undef ACCESSOR_ASSEMBLER_PUBLIC_INTERFACE
1771 1828
1772 } // namespace internal 1829 } // namespace internal
1773 } // namespace v8 1830 } // namespace v8
OLDNEW
« no previous file with comments | « src/factory.cc ('k') | src/ic/accessor-assembler-impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698