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/code-stub-assembler.h" | 5 #include "src/code-stub-assembler.h" |
6 #include "src/code-factory.h" | 6 #include "src/code-factory.h" |
7 #include "src/frames-inl.h" | 7 #include "src/frames-inl.h" |
8 #include "src/frames.h" | 8 #include "src/frames.h" |
9 #include "src/ic/stub-cache.h" | 9 #include "src/ic/stub-cache.h" |
10 | 10 |
(...skipping 3119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3130 TailCallStub(descriptor, handler, p->context, receiver, fake_name, p->slot, | 3130 TailCallStub(descriptor, handler, p->context, receiver, fake_name, p->slot, |
3131 p->vector); | 3131 p->vector); |
3132 } | 3132 } |
3133 Bind(&miss); | 3133 Bind(&miss); |
3134 { | 3134 { |
3135 TailCallRuntime(Runtime::kLoadGlobalIC_Miss, p->context, p->slot, | 3135 TailCallRuntime(Runtime::kLoadGlobalIC_Miss, p->context, p->slot, |
3136 p->vector); | 3136 p->vector); |
3137 } | 3137 } |
3138 } | 3138 } |
3139 | 3139 |
| 3140 Node* CodeStubAssembler::EnumLength(Node* map) { |
| 3141 Node* bitfield_3 = LoadMapBitField3(map); |
| 3142 Node* enum_length = BitFieldDecode<Map::EnumLengthBits>(bitfield_3); |
| 3143 return SmiTag(enum_length); |
| 3144 } |
| 3145 |
| 3146 void CodeStubAssembler::CheckEnumCache(Node* receiver, Label* use_cache, |
| 3147 Label* use_runtime) { |
| 3148 Variable current_js_object(this, MachineRepresentation::kTagged); |
| 3149 current_js_object.Bind(receiver); |
| 3150 |
| 3151 Variable current_map(this, MachineRepresentation::kTagged); |
| 3152 current_map.Bind(LoadMap(current_js_object.value())); |
| 3153 |
| 3154 // These variables are updated in the loop below. |
| 3155 Variable* loop_vars[2] = {¤t_js_object, ¤t_map}; |
| 3156 Label loop(this, 2, loop_vars), next(this); |
| 3157 |
| 3158 // Check if the enum length field is properly initialized, indicating that |
| 3159 // there is an enum cache. |
| 3160 { |
| 3161 Node* invalid_enum_cache_sentinel = |
| 3162 SmiConstant(Smi::FromInt(kInvalidEnumCacheSentinel)); |
| 3163 Node* enum_length = EnumLength(current_map.value()); |
| 3164 BranchIfWordEqual(enum_length, invalid_enum_cache_sentinel, use_runtime, |
| 3165 &loop); |
| 3166 } |
| 3167 |
| 3168 // Check that there are no elements. |current_js_object| contains |
| 3169 // the current JS object we've reached through the prototype chain. |
| 3170 Bind(&loop); |
| 3171 { |
| 3172 Label if_elements(this), if_no_elements(this); |
| 3173 Node* elements = LoadElements(current_js_object.value()); |
| 3174 Node* empty_fixed_array = LoadRoot(Heap::kEmptyFixedArrayRootIndex); |
| 3175 // Check that there are no elements. |
| 3176 BranchIfWordEqual(elements, empty_fixed_array, &if_no_elements, |
| 3177 &if_elements); |
| 3178 Bind(&if_elements); |
| 3179 { |
| 3180 // Second chance, the object may be using the empty slow element |
| 3181 // dictionary. |
| 3182 Node* slow_empty_dictionary = |
| 3183 LoadRoot(Heap::kEmptySlowElementDictionaryRootIndex); |
| 3184 BranchIfWordNotEqual(elements, slow_empty_dictionary, use_runtime, |
| 3185 &if_no_elements); |
| 3186 } |
| 3187 |
| 3188 Bind(&if_no_elements); |
| 3189 { |
| 3190 // Update map prototype. |
| 3191 current_js_object.Bind(LoadMapPrototype(current_map.value())); |
| 3192 BranchIfWordEqual(current_js_object.value(), NullConstant(), use_cache, |
| 3193 &next); |
| 3194 } |
| 3195 } |
| 3196 |
| 3197 Bind(&next); |
| 3198 { |
| 3199 // For all objects but the receiver, check that the cache is empty. |
| 3200 current_map.Bind(LoadMap(current_js_object.value())); |
| 3201 Node* enum_length = EnumLength(current_map.value()); |
| 3202 Node* zero_constant = SmiConstant(Smi::FromInt(0)); |
| 3203 BranchIf(WordEqual(enum_length, zero_constant), &loop, use_runtime); |
| 3204 } |
| 3205 } |
| 3206 |
3140 } // namespace internal | 3207 } // namespace internal |
3141 } // namespace v8 | 3208 } // namespace v8 |
OLD | NEW |