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); |