OLD | NEW |
---|---|
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 | 6 |
7 #include "src/code-factory.h" | 7 #include "src/code-factory.h" |
8 #include "src/code-stubs.h" | 8 #include "src/code-stubs.h" |
9 #include "src/counters.h" | 9 #include "src/counters.h" |
10 #include "src/ic/handler-configuration.h" | 10 #include "src/ic/handler-configuration.h" |
11 #include "src/ic/ic.h" | |
11 #include "src/ic/stub-cache.h" | 12 #include "src/ic/stub-cache.h" |
12 #include "src/objects-inl.h" | 13 #include "src/objects-inl.h" |
13 | 14 |
14 namespace v8 { | 15 namespace v8 { |
15 namespace internal { | 16 namespace internal { |
16 | 17 |
17 using compiler::CodeAssemblerState; | 18 using compiler::CodeAssemblerState; |
18 using compiler::Node; | 19 using compiler::Node; |
19 | 20 |
20 //////////////////// Private helpers. | 21 //////////////////// Private helpers. |
(...skipping 29 matching lines...) Expand all Loading... | |
50 | 51 |
51 var_handler->Bind(handler); | 52 var_handler->Bind(handler); |
52 Goto(if_handler); | 53 Goto(if_handler); |
53 return feedback; | 54 return feedback; |
54 } | 55 } |
55 | 56 |
56 void AccessorAssembler::HandlePolymorphicCase(Node* receiver_map, | 57 void AccessorAssembler::HandlePolymorphicCase(Node* receiver_map, |
57 Node* feedback, Label* if_handler, | 58 Node* feedback, Label* if_handler, |
58 Variable* var_handler, | 59 Variable* var_handler, |
59 Label* if_miss, | 60 Label* if_miss, |
60 int unroll_count) { | 61 int min_feedback_capacity) { |
61 Comment("HandlePolymorphicCase"); | 62 Comment("HandlePolymorphicCase"); |
62 DCHECK_EQ(MachineRepresentation::kTagged, var_handler->rep()); | 63 DCHECK_EQ(MachineRepresentation::kTagged, var_handler->rep()); |
63 | 64 |
64 // Deferred so the unrolled case can omit frame construction in bytecode | 65 // Deferred so the unrolled case can omit frame construction in bytecode |
65 // handler. | 66 // handler. |
66 Label loop(this, Label::kDeferred); | 67 Label loop(this, Label::kDeferred); |
67 | 68 |
68 // Iterate {feedback} array. | 69 // Iterate {feedback} array. |
69 const int kEntrySize = 2; | 70 const int kEntrySize = 2; |
70 | 71 |
71 for (int i = 0; i < unroll_count; i++) { | 72 // Loading feedback's length is delayed until we need it when looking past |
73 // the first {min_feedback_capacity} (map, handler) pairs. | |
74 Node* length = nullptr; | |
75 CSA_ASSERT(this, SmiGreaterThanOrEqual( | |
76 LoadFixedArrayBaseLength(feedback), | |
77 SmiConstant(min_feedback_capacity * kEntrySize))); | |
78 | |
79 const int kUnrolledIterations = IC::kMaxPolymorphicMapCount; | |
80 for (int i = 0; i < kUnrolledIterations; i++) { | |
81 int map_index = i * kEntrySize; | |
82 int handler_index = i * kEntrySize + 1; | |
83 | |
84 if (i >= min_feedback_capacity) { | |
85 if (length == nullptr) length = LoadFixedArrayBaseLength(feedback); | |
86 GotoIf(SmiGreaterThanOrEqual(SmiConstant(handler_index), length), | |
87 if_miss); | |
88 } | |
89 | |
72 Label next_entry(this); | 90 Label next_entry(this); |
73 Node* cached_map = | 91 Node* cached_map = |
74 LoadWeakCellValue(LoadFixedArrayElement(feedback, i * kEntrySize)); | 92 LoadWeakCellValue(LoadFixedArrayElement(feedback, map_index)); |
75 GotoIf(WordNotEqual(receiver_map, cached_map), &next_entry); | 93 GotoIf(WordNotEqual(receiver_map, cached_map), &next_entry); |
76 | 94 |
77 // Found, now call handler. | 95 // Found, now call handler. |
78 Node* handler = LoadFixedArrayElement(feedback, i * kEntrySize + 1); | 96 Node* handler = LoadFixedArrayElement(feedback, handler_index); |
79 var_handler->Bind(handler); | 97 var_handler->Bind(handler); |
80 Goto(if_handler); | 98 Goto(if_handler); |
81 | 99 |
82 Bind(&next_entry); | 100 Bind(&next_entry); |
83 } | 101 } |
84 Goto(&loop); | 102 Goto(&loop); |
85 | 103 |
86 // Loop from {unroll_count}*kEntrySize to {length}. | 104 // Loop from {kUnrolledIterations}*kEntrySize to {length}. |
87 Bind(&loop); | 105 Bind(&loop); |
88 Node* init = IntPtrConstant(unroll_count * kEntrySize); | 106 Node* start_index = IntPtrConstant(kUnrolledIterations * kEntrySize); |
89 Node* length = LoadAndUntagFixedArrayBaseLength(feedback); | 107 Node* end_index = LoadAndUntagFixedArrayBaseLength(feedback); |
Igor Sheludko
2017/03/07 16:28:12
SmiUntag(length)?
Igor Sheludko
2017/03/07 16:30:30
Please ignore this comment.
| |
90 BuildFastLoop( | 108 BuildFastLoop( |
91 init, length, | 109 start_index, end_index, |
92 [this, receiver_map, feedback, if_handler, var_handler](Node* index) { | 110 [this, receiver_map, feedback, if_handler, var_handler](Node* index) { |
93 Node* cached_map = | 111 Node* cached_map = |
94 LoadWeakCellValue(LoadFixedArrayElement(feedback, index)); | 112 LoadWeakCellValue(LoadFixedArrayElement(feedback, index)); |
95 | 113 |
96 Label next_entry(this); | 114 Label next_entry(this); |
97 GotoIf(WordNotEqual(receiver_map, cached_map), &next_entry); | 115 GotoIf(WordNotEqual(receiver_map, cached_map), &next_entry); |
98 | 116 |
99 // Found, now call handler. | 117 // Found, now call handler. |
100 Node* handler = LoadFixedArrayElement(feedback, index, kPointerSize); | 118 Node* handler = LoadFixedArrayElement(feedback, index, kPointerSize); |
101 var_handler->Bind(handler); | 119 var_handler->Bind(handler); |
(...skipping 2256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2358 Node* context = Parameter(Descriptor::kContext); | 2376 Node* context = Parameter(Descriptor::kContext); |
2359 Node* vector = LoadFeedbackVectorForStub(); | 2377 Node* vector = LoadFeedbackVectorForStub(); |
2360 | 2378 |
2361 Callable callable = | 2379 Callable callable = |
2362 CodeFactory::KeyedStoreICInOptimizedCode(isolate(), language_mode); | 2380 CodeFactory::KeyedStoreICInOptimizedCode(isolate(), language_mode); |
2363 TailCallStub(callable, context, receiver, name, value, slot, vector); | 2381 TailCallStub(callable, context, receiver, name, value, slot, vector); |
2364 } | 2382 } |
2365 | 2383 |
2366 } // namespace internal | 2384 } // namespace internal |
2367 } // namespace v8 | 2385 } // namespace v8 |
OLD | NEW |