Chromium Code Reviews| Index: src/ic/accessor-assembler.cc |
| diff --git a/src/ic/accessor-assembler.cc b/src/ic/accessor-assembler.cc |
| index 00d8cad62687e956edbd1d7cf8c1354f3cd91457..ed07f6e30a798679d9747918c392c1789cc0982e 100644 |
| --- a/src/ic/accessor-assembler.cc |
| +++ b/src/ic/accessor-assembler.cc |
| @@ -8,6 +8,7 @@ |
| #include "src/code-stubs.h" |
| #include "src/counters.h" |
| #include "src/ic/handler-configuration.h" |
| +#include "src/ic/ic.h" |
| #include "src/ic/stub-cache.h" |
| #include "src/objects-inl.h" |
| @@ -68,14 +69,30 @@ void AccessorAssembler::HandlePolymorphicCase(Node* receiver_map, |
| // Iterate {feedback} array. |
| const int kEntrySize = 2; |
| + // Polymorphic IC feedback is guaranteed contain at least two (map, handler) |
| + // pairs. |
| + const int kMaxUnrollCountWithoutBoundsCheck = 2; |
| + DCHECK_LE(unroll_count, IC::kMaxPolymorphicMapCount); |
| + |
| + Node* length = LoadAndUntagFixedArrayBaseLength(feedback); |
|
Igor Sheludko
2017/03/07 13:24:01
We can delay loading of a length till (i == kMaxUn
|
| + CSA_ASSERT(this, IntPtrGreaterThanOrEqual(length, IntPtrConstant(2))); |
| + |
| for (int i = 0; i < unroll_count; i++) { |
| + int map_index = i * kEntrySize; |
| + int handler_index = i * kEntrySize + 1; |
| + |
| + if (i >= kMaxUnrollCountWithoutBoundsCheck) { |
| + GotoIf(IntPtrGreaterThanOrEqual(IntPtrConstant(handler_index), length), |
| + if_miss); |
| + } |
| + |
| Label next_entry(this); |
| Node* cached_map = |
| - LoadWeakCellValue(LoadFixedArrayElement(feedback, i * kEntrySize)); |
| + LoadWeakCellValue(LoadFixedArrayElement(feedback, map_index)); |
| GotoIf(WordNotEqual(receiver_map, cached_map), &next_entry); |
| // Found, now call handler. |
| - Node* handler = LoadFixedArrayElement(feedback, i * kEntrySize + 1); |
| + Node* handler = LoadFixedArrayElement(feedback, handler_index); |
| var_handler->Bind(handler); |
| Goto(if_handler); |
| @@ -86,7 +103,6 @@ void AccessorAssembler::HandlePolymorphicCase(Node* receiver_map, |
| // Loop from {unroll_count}*kEntrySize to {length}. |
| Bind(&loop); |
| Node* init = IntPtrConstant(unroll_count * kEntrySize); |
| - Node* length = LoadAndUntagFixedArrayBaseLength(feedback); |
| BuildFastLoop( |
| init, length, |
| [this, receiver_map, feedback, if_handler, var_handler](Node* index) { |
| @@ -1628,7 +1644,7 @@ void AccessorAssembler::LoadIC_BytecodeHandler(const LoadICParameters* p, |
| GotoIfNot(WordEqual(LoadMap(feedback), FixedArrayMapConstant()), |
| &stub_call); |
| HandlePolymorphicCase(recv_map, feedback, &if_handler, &var_handler, |
| - &miss, 2); |
| + &miss, IC::kMaxPolymorphicMapCount); |
| } |
| } |
| @@ -1678,7 +1694,7 @@ void AccessorAssembler::LoadIC(const LoadICParameters* p) { |
| GotoIfNot(WordEqual(LoadMap(feedback), FixedArrayMapConstant()), |
| &non_inlined); |
| HandlePolymorphicCase(receiver_map, feedback, &if_handler, &var_handler, |
| - &miss, 2); |
| + &miss, IC::kMaxPolymorphicMapCount); |
| } |
| Bind(&non_inlined); |
| @@ -1910,7 +1926,7 @@ void AccessorAssembler::KeyedLoadIC(const LoadICParameters* p) { |
| GotoIfNot(WordEqual(LoadMap(feedback), FixedArrayMapConstant()), |
| &try_megamorphic); |
| HandlePolymorphicCase(receiver_map, feedback, &if_handler, &var_handler, |
| - &miss, 2); |
| + &miss, IC::kMaxPolymorphicMapCount); |
| } |
| Bind(&try_megamorphic); |
| @@ -2005,7 +2021,7 @@ void AccessorAssembler::StoreIC(const StoreICParameters* p) { |
| WordEqual(LoadMap(feedback), LoadRoot(Heap::kFixedArrayMapRootIndex)), |
| &try_megamorphic); |
| HandlePolymorphicCase(receiver_map, feedback, &if_handler, &var_handler, |
| - &miss, 2); |
| + &miss, IC::kMaxPolymorphicMapCount); |
| } |
| Bind(&try_megamorphic); |