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

Side by Side Diff: src/ic/accessor-assembler.cc

Issue 2688503002: [ic] Refactor LoadGlobalIC in preparation for handler inlining (Closed)
Patch Set: Created 3 years, 10 months 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
« src/ic/accessor-assembler.h ('K') | « src/ic/accessor-assembler.h ('k') | no next file » | 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 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/ic/handler-configuration.h" 9 #include "src/ic/handler-configuration.h"
10 #include "src/ic/stub-cache.h" 10 #include "src/ic/stub-cache.h"
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
134 }, 134 },
135 kEntrySize, INTPTR_PARAMETERS, IndexAdvanceMode::kPost); 135 kEntrySize, INTPTR_PARAMETERS, IndexAdvanceMode::kPost);
136 // The loop falls through if no handler was found. 136 // The loop falls through if no handler was found.
137 Goto(if_miss); 137 Goto(if_miss);
138 } 138 }
139 139
140 void AccessorAssembler::HandleLoadICHandlerCase( 140 void AccessorAssembler::HandleLoadICHandlerCase(
141 const LoadICParameters* p, Node* handler, Label* miss, 141 const LoadICParameters* p, Node* handler, Label* miss,
142 ElementSupport support_elements) { 142 ElementSupport support_elements) {
143 Comment("have_handler"); 143 Comment("have_handler");
144 ExitPoint direct_exit(this);
145
144 Variable var_holder(this, MachineRepresentation::kTagged); 146 Variable var_holder(this, MachineRepresentation::kTagged);
145 var_holder.Bind(p->receiver); 147 var_holder.Bind(p->receiver);
146 Variable var_smi_handler(this, MachineRepresentation::kTagged); 148 Variable var_smi_handler(this, MachineRepresentation::kTagged);
147 var_smi_handler.Bind(handler); 149 var_smi_handler.Bind(handler);
148 150
149 Variable* vars[] = {&var_holder, &var_smi_handler}; 151 Variable* vars[] = {&var_holder, &var_smi_handler};
150 Label if_smi_handler(this, 2, vars); 152 Label if_smi_handler(this, 2, vars);
151 Label try_proto_handler(this), call_handler(this); 153 Label try_proto_handler(this), call_handler(this);
152 154
153 Branch(TaggedIsSmi(handler), &if_smi_handler, &try_proto_handler); 155 Branch(TaggedIsSmi(handler), &if_smi_handler, &try_proto_handler);
154 156
155 // |handler| is a Smi, encoding what to do. See SmiHandler methods 157 // |handler| is a Smi, encoding what to do. See SmiHandler methods
156 // for the encoding format. 158 // for the encoding format.
157 Bind(&if_smi_handler); 159 Bind(&if_smi_handler);
158 { 160 {
159 HandleLoadICSmiHandlerCase(p, var_holder.value(), var_smi_handler.value(), 161 HandleLoadICSmiHandlerCase(p, var_holder.value(), var_smi_handler.value(),
160 miss, support_elements); 162 miss, &direct_exit, support_elements);
161 } 163 }
162 164
163 Bind(&try_proto_handler); 165 Bind(&try_proto_handler);
164 { 166 {
165 GotoIf(IsCodeMap(LoadMap(handler)), &call_handler); 167 GotoIf(IsCodeMap(LoadMap(handler)), &call_handler);
166 HandleLoadICProtoHandlerCase(p, handler, &var_holder, &var_smi_handler, 168 HandleLoadICProtoHandlerCase(p, handler, &var_holder, &var_smi_handler,
167 &if_smi_handler, miss, false); 169 &if_smi_handler, miss, &direct_exit, false);
168 } 170 }
169 171
170 Bind(&call_handler); 172 Bind(&call_handler);
171 { 173 {
172 typedef LoadWithVectorDescriptor Descriptor; 174 typedef LoadWithVectorDescriptor Descriptor;
173 TailCallStub(Descriptor(isolate()), handler, p->context, p->receiver, 175 TailCallStub(Descriptor(isolate()), handler, p->context, p->receiver,
174 p->name, p->slot, p->vector); 176 p->name, p->slot, p->vector);
175 } 177 }
176 } 178 }
177 179
178 void AccessorAssembler::HandleLoadICSmiHandlerCase( 180 void AccessorAssembler::HandleLoadICSmiHandlerCase(
179 const LoadICParameters* p, Node* holder, Node* smi_handler, Label* miss, 181 const LoadICParameters* p, Node* holder, Node* smi_handler, Label* miss,
180 ElementSupport support_elements) { 182 ExitPoint* exit_point, ElementSupport support_elements) {
181 Variable var_double_value(this, MachineRepresentation::kFloat64); 183 Variable var_double_value(this, MachineRepresentation::kFloat64);
182 Label rebox_double(this, &var_double_value); 184 Label rebox_double(this, &var_double_value);
183 185
184 Node* handler_word = SmiUntag(smi_handler); 186 Node* handler_word = SmiUntag(smi_handler);
185 Node* handler_kind = DecodeWord<LoadHandler::KindBits>(handler_word); 187 Node* handler_kind = DecodeWord<LoadHandler::KindBits>(handler_word);
186 if (support_elements == kSupportElements) { 188 if (support_elements == kSupportElements) {
187 Label property(this); 189 Label property(this);
188 GotoUnless( 190 GotoUnless(
189 WordEqual(handler_kind, IntPtrConstant(LoadHandler::kForElements)), 191 WordEqual(handler_kind, IntPtrConstant(LoadHandler::kForElements)),
190 &property); 192 &property);
191 193
192 Comment("element_load"); 194 Comment("element_load");
193 Node* intptr_index = TryToIntptr(p->name, miss); 195 Node* intptr_index = TryToIntptr(p->name, miss);
194 Node* elements = LoadElements(holder); 196 Node* elements = LoadElements(holder);
195 Node* is_jsarray_condition = 197 Node* is_jsarray_condition =
196 IsSetWord<LoadHandler::IsJsArrayBits>(handler_word); 198 IsSetWord<LoadHandler::IsJsArrayBits>(handler_word);
197 Node* elements_kind = 199 Node* elements_kind =
198 DecodeWord32FromWord<LoadHandler::ElementsKindBits>(handler_word); 200 DecodeWord32FromWord<LoadHandler::ElementsKindBits>(handler_word);
199 Label if_hole(this), unimplemented_elements_kind(this); 201 Label if_hole(this), unimplemented_elements_kind(this);
200 Label* out_of_bounds = miss; 202 Label* out_of_bounds = miss;
201 EmitElementLoad(holder, elements, elements_kind, intptr_index, 203 EmitElementLoad(holder, elements, elements_kind, intptr_index,
202 is_jsarray_condition, &if_hole, &rebox_double, 204 is_jsarray_condition, &if_hole, &rebox_double,
203 &var_double_value, &unimplemented_elements_kind, 205 &var_double_value, &unimplemented_elements_kind,
204 out_of_bounds, miss); 206 out_of_bounds, miss, exit_point);
205 207
206 Bind(&unimplemented_elements_kind); 208 Bind(&unimplemented_elements_kind);
207 { 209 {
208 // Smi handlers should only be installed for supported elements kinds. 210 // Smi handlers should only be installed for supported elements kinds.
209 // Crash if we get here. 211 // Crash if we get here.
210 DebugBreak(); 212 DebugBreak();
211 Goto(miss); 213 Goto(miss);
212 } 214 }
213 215
214 Bind(&if_hole); 216 Bind(&if_hole);
215 { 217 {
216 Comment("convert hole"); 218 Comment("convert hole");
217 GotoUnless(IsSetWord<LoadHandler::ConvertHoleBits>(handler_word), miss); 219 GotoUnless(IsSetWord<LoadHandler::ConvertHoleBits>(handler_word), miss);
218 Node* protector_cell = LoadRoot(Heap::kArrayProtectorRootIndex); 220 Node* protector_cell = LoadRoot(Heap::kArrayProtectorRootIndex);
219 DCHECK(isolate()->heap()->array_protector()->IsPropertyCell()); 221 DCHECK(isolate()->heap()->array_protector()->IsPropertyCell());
220 GotoUnless( 222 GotoUnless(
221 WordEqual(LoadObjectField(protector_cell, PropertyCell::kValueOffset), 223 WordEqual(LoadObjectField(protector_cell, PropertyCell::kValueOffset),
222 SmiConstant(Smi::FromInt(Isolate::kProtectorValid))), 224 SmiConstant(Smi::FromInt(Isolate::kProtectorValid))),
223 miss); 225 miss);
224 Return(UndefinedConstant()); 226 exit_point->Return(UndefinedConstant());
225 } 227 }
226 228
227 Bind(&property); 229 Bind(&property);
228 Comment("property_load"); 230 Comment("property_load");
229 } 231 }
230 232
231 Label constant(this), field(this); 233 Label constant(this), field(this);
232 Branch(WordEqual(handler_kind, IntPtrConstant(LoadHandler::kForFields)), 234 Branch(WordEqual(handler_kind, IntPtrConstant(LoadHandler::kForFields)),
233 &field, &constant); 235 &field, &constant);
234 236
235 Bind(&field); 237 Bind(&field);
236 { 238 {
237 Comment("field_load"); 239 Comment("field_load");
238 Node* offset = DecodeWord<LoadHandler::FieldOffsetBits>(handler_word); 240 Node* offset = DecodeWord<LoadHandler::FieldOffsetBits>(handler_word);
239 241
240 Label inobject(this), out_of_object(this); 242 Label inobject(this), out_of_object(this);
241 Branch(IsSetWord<LoadHandler::IsInobjectBits>(handler_word), &inobject, 243 Branch(IsSetWord<LoadHandler::IsInobjectBits>(handler_word), &inobject,
242 &out_of_object); 244 &out_of_object);
243 245
244 Bind(&inobject); 246 Bind(&inobject);
245 { 247 {
246 Label is_double(this); 248 Label is_double(this);
247 GotoIf(IsSetWord<LoadHandler::IsDoubleBits>(handler_word), &is_double); 249 GotoIf(IsSetWord<LoadHandler::IsDoubleBits>(handler_word), &is_double);
248 Return(LoadObjectField(holder, offset)); 250 exit_point->Return(LoadObjectField(holder, offset));
249 251
250 Bind(&is_double); 252 Bind(&is_double);
251 if (FLAG_unbox_double_fields) { 253 if (FLAG_unbox_double_fields) {
252 var_double_value.Bind( 254 var_double_value.Bind(
253 LoadObjectField(holder, offset, MachineType::Float64())); 255 LoadObjectField(holder, offset, MachineType::Float64()));
254 } else { 256 } else {
255 Node* mutable_heap_number = LoadObjectField(holder, offset); 257 Node* mutable_heap_number = LoadObjectField(holder, offset);
256 var_double_value.Bind(LoadHeapNumberValue(mutable_heap_number)); 258 var_double_value.Bind(LoadHeapNumberValue(mutable_heap_number));
257 } 259 }
258 Goto(&rebox_double); 260 Goto(&rebox_double);
259 } 261 }
260 262
261 Bind(&out_of_object); 263 Bind(&out_of_object);
262 { 264 {
263 Label is_double(this); 265 Label is_double(this);
264 Node* properties = LoadProperties(holder); 266 Node* properties = LoadProperties(holder);
265 Node* value = LoadObjectField(properties, offset); 267 Node* value = LoadObjectField(properties, offset);
266 GotoIf(IsSetWord<LoadHandler::IsDoubleBits>(handler_word), &is_double); 268 GotoIf(IsSetWord<LoadHandler::IsDoubleBits>(handler_word), &is_double);
267 Return(value); 269 exit_point->Return(value);
268 270
269 Bind(&is_double); 271 Bind(&is_double);
270 var_double_value.Bind(LoadHeapNumberValue(value)); 272 var_double_value.Bind(LoadHeapNumberValue(value));
271 Goto(&rebox_double); 273 Goto(&rebox_double);
272 } 274 }
273 275
274 Bind(&rebox_double); 276 Bind(&rebox_double);
275 Return(AllocateHeapNumberWithValue(var_double_value.value())); 277 exit_point->Return(AllocateHeapNumberWithValue(var_double_value.value()));
276 } 278 }
277 279
278 Bind(&constant); 280 Bind(&constant);
279 { 281 {
280 Comment("constant_load"); 282 Comment("constant_load");
281 Node* descriptors = LoadMapDescriptors(LoadMap(holder)); 283 Node* descriptors = LoadMapDescriptors(LoadMap(holder));
282 Node* descriptor = 284 Node* descriptor =
283 DecodeWord<LoadHandler::DescriptorValueIndexBits>(handler_word); 285 DecodeWord<LoadHandler::DescriptorValueIndexBits>(handler_word);
284 CSA_ASSERT(this, 286 CSA_ASSERT(this,
285 UintPtrLessThan(descriptor, 287 UintPtrLessThan(descriptor,
286 LoadAndUntagFixedArrayBaseLength(descriptors))); 288 LoadAndUntagFixedArrayBaseLength(descriptors)));
287 Node* value = LoadFixedArrayElement(descriptors, descriptor); 289 Node* value = LoadFixedArrayElement(descriptors, descriptor);
288 290
289 Label if_accessor_info(this); 291 Label if_accessor_info(this);
290 GotoIf(IsSetWord<LoadHandler::IsAccessorInfoBits>(handler_word), 292 GotoIf(IsSetWord<LoadHandler::IsAccessorInfoBits>(handler_word),
291 &if_accessor_info); 293 &if_accessor_info);
292 Return(value); 294 exit_point->Return(value);
293 295
294 Bind(&if_accessor_info); 296 Bind(&if_accessor_info);
295 Callable callable = CodeFactory::ApiGetter(isolate()); 297 Callable callable = CodeFactory::ApiGetter(isolate());
296 TailCallStub(callable, p->context, p->receiver, holder, value); 298 exit_point->ReturnStub(callable, p->context, p->receiver, holder, value);
297 } 299 }
298 } 300 }
299 301
300 void AccessorAssembler::HandleLoadICProtoHandlerCase( 302 void AccessorAssembler::HandleLoadICProtoHandlerCase(
301 const LoadICParameters* p, Node* handler, Variable* var_holder, 303 const LoadICParameters* p, Node* handler, Variable* var_holder,
302 Variable* var_smi_handler, Label* if_smi_handler, Label* miss, 304 Variable* var_smi_handler, Label* if_smi_handler, Label* miss,
303 bool throw_reference_error_if_nonexistent) { 305 ExitPoint* exit_point, bool throw_reference_error_if_nonexistent) {
304 DCHECK_EQ(MachineRepresentation::kTagged, var_holder->rep()); 306 DCHECK_EQ(MachineRepresentation::kTagged, var_holder->rep());
305 DCHECK_EQ(MachineRepresentation::kTagged, var_smi_handler->rep()); 307 DCHECK_EQ(MachineRepresentation::kTagged, var_smi_handler->rep());
306 308
307 // IC dispatchers rely on these assumptions to be held. 309 // IC dispatchers rely on these assumptions to be held.
308 STATIC_ASSERT(FixedArray::kLengthOffset == LoadHandler::kHolderCellOffset); 310 STATIC_ASSERT(FixedArray::kLengthOffset == LoadHandler::kHolderCellOffset);
309 DCHECK_EQ(FixedArray::OffsetOfElementAt(LoadHandler::kSmiHandlerIndex), 311 DCHECK_EQ(FixedArray::OffsetOfElementAt(LoadHandler::kSmiHandlerIndex),
310 LoadHandler::kSmiHandlerOffset); 312 LoadHandler::kSmiHandlerOffset);
311 DCHECK_EQ(FixedArray::OffsetOfElementAt(LoadHandler::kValidityCellIndex), 313 DCHECK_EQ(FixedArray::OffsetOfElementAt(LoadHandler::kValidityCellIndex),
312 LoadHandler::kValidityCellOffset); 314 LoadHandler::kValidityCellOffset);
313 315
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
345 LoadObjectField(handler, LoadHandler::kHolderCellOffset); 347 LoadObjectField(handler, LoadHandler::kHolderCellOffset);
346 Label array_handler(this), tuple_handler(this); 348 Label array_handler(this), tuple_handler(this);
347 Branch(TaggedIsSmi(maybe_holder_cell), &array_handler, &tuple_handler); 349 Branch(TaggedIsSmi(maybe_holder_cell), &array_handler, &tuple_handler);
348 350
349 Bind(&tuple_handler); 351 Bind(&tuple_handler);
350 { 352 {
351 Label load_existent(this); 353 Label load_existent(this);
352 GotoIf(WordNotEqual(maybe_holder_cell, NullConstant()), &load_existent); 354 GotoIf(WordNotEqual(maybe_holder_cell, NullConstant()), &load_existent);
353 // This is a handler for a load of a non-existent value. 355 // This is a handler for a load of a non-existent value.
354 if (throw_reference_error_if_nonexistent) { 356 if (throw_reference_error_if_nonexistent) {
355 TailCallRuntime(Runtime::kThrowReferenceError, p->context, p->name); 357 exit_point->ReturnRuntime(Runtime::kThrowReferenceError, p->context,
358 p->name);
356 } else { 359 } else {
357 Return(UndefinedConstant()); 360 exit_point->Return(UndefinedConstant());
358 } 361 }
359 362
360 Bind(&load_existent); 363 Bind(&load_existent);
361 Node* holder = LoadWeakCellValue(maybe_holder_cell); 364 Node* holder = LoadWeakCellValue(maybe_holder_cell);
362 // The |holder| is guaranteed to be alive at this point since we passed 365 // The |holder| is guaranteed to be alive at this point since we passed
363 // both the receiver map check and the validity cell check. 366 // both the receiver map check and the validity cell check.
364 CSA_ASSERT(this, WordNotEqual(holder, IntPtrConstant(0))); 367 CSA_ASSERT(this, WordNotEqual(holder, IntPtrConstant(0)));
365 368
366 var_holder->Bind(holder); 369 var_holder->Bind(holder);
367 var_smi_handler->Bind(smi_handler); 370 var_smi_handler->Bind(smi_handler);
368 Goto(if_smi_handler); 371 Goto(if_smi_handler);
369 } 372 }
370 373
371 Bind(&array_handler); 374 Bind(&array_handler);
372 { 375 {
373 TailCallStub(CodeFactory::LoadICProtoArray( 376 exit_point->ReturnStub(CodeFactory::LoadICProtoArray(
374 isolate(), throw_reference_error_if_nonexistent), 377 isolate(), throw_reference_error_if_nonexistent),
375 p->context, p->receiver, p->name, p->slot, p->vector, handler); 378 p->context, p->receiver, p->name, p->slot, p->vector,
379 handler);
376 } 380 }
377 } 381 }
378 382
379 Node* AccessorAssembler::EmitLoadICProtoArrayCheck( 383 Node* AccessorAssembler::EmitLoadICProtoArrayCheck(
380 const LoadICParameters* p, Node* handler, Node* handler_length, 384 const LoadICParameters* p, Node* handler, Node* handler_length,
381 Node* handler_flags, Label* miss, 385 Node* handler_flags, Label* miss,
382 bool throw_reference_error_if_nonexistent) { 386 bool throw_reference_error_if_nonexistent) {
383 Variable start_index(this, MachineType::PointerRepresentation()); 387 Variable start_index(this, MachineType::PointerRepresentation());
384 start_index.Bind(IntPtrConstant(LoadHandler::kFirstPrototypeIndex)); 388 start_index.Bind(IntPtrConstant(LoadHandler::kFirstPrototypeIndex));
385 389
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
433 Node* holder = LoadWeakCellValue(maybe_holder_cell); 437 Node* holder = LoadWeakCellValue(maybe_holder_cell);
434 // The |holder| is guaranteed to be alive at this point since we passed 438 // The |holder| is guaranteed to be alive at this point since we passed
435 // the receiver map check, the validity cell check and the prototype chain 439 // the receiver map check, the validity cell check and the prototype chain
436 // check. 440 // check.
437 CSA_ASSERT(this, WordNotEqual(holder, IntPtrConstant(0))); 441 CSA_ASSERT(this, WordNotEqual(holder, IntPtrConstant(0)));
438 return holder; 442 return holder;
439 } 443 }
440 444
441 void AccessorAssembler::HandleLoadGlobalICHandlerCase( 445 void AccessorAssembler::HandleLoadGlobalICHandlerCase(
442 const LoadICParameters* pp, Node* handler, Label* miss, 446 const LoadICParameters* pp, Node* handler, Label* miss,
443 bool throw_reference_error_if_nonexistent) { 447 ExitPoint* exit_point, bool throw_reference_error_if_nonexistent) {
444 LoadICParameters p = *pp; 448 LoadICParameters p = *pp;
445 DCHECK_NULL(p.receiver); 449 DCHECK_NULL(p.receiver);
446 Node* native_context = LoadNativeContext(p.context); 450 Node* native_context = LoadNativeContext(p.context);
447 p.receiver = LoadContextElement(native_context, Context::EXTENSION_INDEX); 451 p.receiver = LoadContextElement(native_context, Context::EXTENSION_INDEX);
448 452
449 Variable var_holder(this, MachineRepresentation::kTagged); 453 Variable var_holder(this, MachineRepresentation::kTagged);
450 Variable var_smi_handler(this, MachineRepresentation::kTagged); 454 Variable var_smi_handler(this, MachineRepresentation::kTagged);
451 Label if_smi_handler(this); 455 Label if_smi_handler(this);
452 HandleLoadICProtoHandlerCase(&p, handler, &var_holder, &var_smi_handler, 456 HandleLoadICProtoHandlerCase(&p, handler, &var_holder, &var_smi_handler,
453 &if_smi_handler, miss, 457 &if_smi_handler, miss, exit_point,
454 throw_reference_error_if_nonexistent); 458 throw_reference_error_if_nonexistent);
455 Bind(&if_smi_handler); 459 Bind(&if_smi_handler);
456 HandleLoadICSmiHandlerCase(&p, var_holder.value(), var_smi_handler.value(), 460 HandleLoadICSmiHandlerCase(&p, var_holder.value(), var_smi_handler.value(),
457 miss, kOnlyProperties); 461 miss, exit_point, kOnlyProperties);
458 } 462 }
459 463
460 void AccessorAssembler::HandleStoreICHandlerCase( 464 void AccessorAssembler::HandleStoreICHandlerCase(
461 const StoreICParameters* p, Node* handler, Label* miss, 465 const StoreICParameters* p, Node* handler, Label* miss,
462 ElementSupport support_elements) { 466 ElementSupport support_elements) {
463 Label if_smi_handler(this), if_nonsmi_handler(this); 467 Label if_smi_handler(this), if_nonsmi_handler(this);
464 Label if_proto_handler(this), if_element_handler(this), call_handler(this); 468 Label if_proto_handler(this), if_element_handler(this), call_handler(this);
465 469
466 Branch(TaggedIsSmi(handler), &if_smi_handler, &if_nonsmi_handler); 470 Branch(TaggedIsSmi(handler), &if_smi_handler, &if_nonsmi_handler);
467 471
(...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after
849 } 853 }
850 Bind(&if_array); 854 Bind(&if_array);
851 { 855 {
852 var_length.Bind(SmiUntag(LoadJSArrayLength(object))); 856 var_length.Bind(SmiUntag(LoadJSArrayLength(object)));
853 Goto(&length_loaded); 857 Goto(&length_loaded);
854 } 858 }
855 Bind(&length_loaded); 859 Bind(&length_loaded);
856 GotoUnless(UintPtrLessThan(intptr_index, var_length.value()), miss); 860 GotoUnless(UintPtrLessThan(intptr_index, var_length.value()), miss);
857 } 861 }
858 862
859 void AccessorAssembler::EmitElementLoad(Node* object, Node* elements, 863 void AccessorAssembler::EmitElementLoad(
860 Node* elements_kind, Node* intptr_index, 864 Node* object, Node* elements, Node* elements_kind, Node* intptr_index,
861 Node* is_jsarray_condition, 865 Node* is_jsarray_condition, Label* if_hole, Label* rebox_double,
862 Label* if_hole, Label* rebox_double, 866 Variable* var_double_value, Label* unimplemented_elements_kind,
863 Variable* var_double_value, 867 Label* out_of_bounds, Label* miss, ExitPoint* exit_point) {
864 Label* unimplemented_elements_kind,
865 Label* out_of_bounds, Label* miss) {
866 Label if_typed_array(this), if_fast_packed(this), if_fast_holey(this), 868 Label if_typed_array(this), if_fast_packed(this), if_fast_holey(this),
867 if_fast_double(this), if_fast_holey_double(this), if_nonfast(this), 869 if_fast_double(this), if_fast_holey_double(this), if_nonfast(this),
868 if_dictionary(this); 870 if_dictionary(this);
869 GotoIf( 871 GotoIf(
870 Int32GreaterThan(elements_kind, Int32Constant(LAST_FAST_ELEMENTS_KIND)), 872 Int32GreaterThan(elements_kind, Int32Constant(LAST_FAST_ELEMENTS_KIND)),
871 &if_nonfast); 873 &if_nonfast);
872 874
873 EmitFastElementsBoundsCheck(object, elements, intptr_index, 875 EmitFastElementsBoundsCheck(object, elements, intptr_index,
874 is_jsarray_condition, out_of_bounds); 876 is_jsarray_condition, out_of_bounds);
875 int32_t kinds[] = {// Handled by if_fast_packed. 877 int32_t kinds[] = {// Handled by if_fast_packed.
(...skipping 11 matching lines...) Expand all
887 // FAST_DOUBLE_ELEMENTS 889 // FAST_DOUBLE_ELEMENTS
888 &if_fast_double, 890 &if_fast_double,
889 // FAST_HOLEY_DOUBLE_ELEMENTS 891 // FAST_HOLEY_DOUBLE_ELEMENTS
890 &if_fast_holey_double}; 892 &if_fast_holey_double};
891 Switch(elements_kind, unimplemented_elements_kind, kinds, labels, 893 Switch(elements_kind, unimplemented_elements_kind, kinds, labels,
892 arraysize(kinds)); 894 arraysize(kinds));
893 895
894 Bind(&if_fast_packed); 896 Bind(&if_fast_packed);
895 { 897 {
896 Comment("fast packed elements"); 898 Comment("fast packed elements");
897 Return(LoadFixedArrayElement(elements, intptr_index)); 899 exit_point->Return(LoadFixedArrayElement(elements, intptr_index));
898 } 900 }
899 901
900 Bind(&if_fast_holey); 902 Bind(&if_fast_holey);
901 { 903 {
902 Comment("fast holey elements"); 904 Comment("fast holey elements");
903 Node* element = LoadFixedArrayElement(elements, intptr_index); 905 Node* element = LoadFixedArrayElement(elements, intptr_index);
904 GotoIf(WordEqual(element, TheHoleConstant()), if_hole); 906 GotoIf(WordEqual(element, TheHoleConstant()), if_hole);
905 Return(element); 907 exit_point->Return(element);
906 } 908 }
907 909
908 Bind(&if_fast_double); 910 Bind(&if_fast_double);
909 { 911 {
910 Comment("packed double elements"); 912 Comment("packed double elements");
911 var_double_value->Bind(LoadFixedDoubleArrayElement(elements, intptr_index, 913 var_double_value->Bind(LoadFixedDoubleArrayElement(elements, intptr_index,
912 MachineType::Float64())); 914 MachineType::Float64()));
913 Goto(rebox_double); 915 Goto(rebox_double);
914 } 916 }
915 917
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
947 // Check that the value is a data property. 949 // Check that the value is a data property.
948 Node* details_index = EntryToIndex<SeededNumberDictionary>( 950 Node* details_index = EntryToIndex<SeededNumberDictionary>(
949 var_entry.value(), SeededNumberDictionary::kEntryDetailsIndex); 951 var_entry.value(), SeededNumberDictionary::kEntryDetailsIndex);
950 Node* details = SmiToWord32(LoadFixedArrayElement(elements, details_index)); 952 Node* details = SmiToWord32(LoadFixedArrayElement(elements, details_index));
951 Node* kind = DecodeWord32<PropertyDetails::KindField>(details); 953 Node* kind = DecodeWord32<PropertyDetails::KindField>(details);
952 // TODO(jkummerow): Support accessors without missing? 954 // TODO(jkummerow): Support accessors without missing?
953 GotoUnless(Word32Equal(kind, Int32Constant(kData)), miss); 955 GotoUnless(Word32Equal(kind, Int32Constant(kData)), miss);
954 // Finally, load the value. 956 // Finally, load the value.
955 Node* value_index = EntryToIndex<SeededNumberDictionary>( 957 Node* value_index = EntryToIndex<SeededNumberDictionary>(
956 var_entry.value(), SeededNumberDictionary::kEntryValueIndex); 958 var_entry.value(), SeededNumberDictionary::kEntryValueIndex);
957 Return(LoadFixedArrayElement(elements, value_index)); 959 exit_point->Return(LoadFixedArrayElement(elements, value_index));
958 } 960 }
959 961
960 Bind(&if_typed_array); 962 Bind(&if_typed_array);
961 { 963 {
962 Comment("typed elements"); 964 Comment("typed elements");
963 // Check if buffer has been neutered. 965 // Check if buffer has been neutered.
964 Node* buffer = LoadObjectField(object, JSArrayBufferView::kBufferOffset); 966 Node* buffer = LoadObjectField(object, JSArrayBufferView::kBufferOffset);
965 GotoIf(IsDetachedBuffer(buffer), miss); 967 GotoIf(IsDetachedBuffer(buffer), miss);
966 968
967 // Bounds check. 969 // Bounds check.
(...skipping 25 matching lines...) Expand all
993 LAST_FIXED_TYPED_ARRAY_ELEMENTS_KIND - 995 LAST_FIXED_TYPED_ARRAY_ELEMENTS_KIND -
994 FIRST_FIXED_TYPED_ARRAY_ELEMENTS_KIND + 1; 996 FIRST_FIXED_TYPED_ARRAY_ELEMENTS_KIND + 1;
995 DCHECK_EQ(kTypedElementsKindCount, arraysize(elements_kinds)); 997 DCHECK_EQ(kTypedElementsKindCount, arraysize(elements_kinds));
996 DCHECK_EQ(kTypedElementsKindCount, arraysize(elements_kind_labels)); 998 DCHECK_EQ(kTypedElementsKindCount, arraysize(elements_kind_labels));
997 Switch(elements_kind, miss, elements_kinds, elements_kind_labels, 999 Switch(elements_kind, miss, elements_kinds, elements_kind_labels,
998 kTypedElementsKindCount); 1000 kTypedElementsKindCount);
999 Bind(&uint8_elements); 1001 Bind(&uint8_elements);
1000 { 1002 {
1001 Comment("UINT8_ELEMENTS"); // Handles UINT8_CLAMPED_ELEMENTS too. 1003 Comment("UINT8_ELEMENTS"); // Handles UINT8_CLAMPED_ELEMENTS too.
1002 Node* element = Load(MachineType::Uint8(), backing_store, intptr_index); 1004 Node* element = Load(MachineType::Uint8(), backing_store, intptr_index);
1003 Return(SmiFromWord32(element)); 1005 exit_point->Return(SmiFromWord32(element));
1004 } 1006 }
1005 Bind(&int8_elements); 1007 Bind(&int8_elements);
1006 { 1008 {
1007 Comment("INT8_ELEMENTS"); 1009 Comment("INT8_ELEMENTS");
1008 Node* element = Load(MachineType::Int8(), backing_store, intptr_index); 1010 Node* element = Load(MachineType::Int8(), backing_store, intptr_index);
1009 Return(SmiFromWord32(element)); 1011 exit_point->Return(SmiFromWord32(element));
1010 } 1012 }
1011 Bind(&uint16_elements); 1013 Bind(&uint16_elements);
1012 { 1014 {
1013 Comment("UINT16_ELEMENTS"); 1015 Comment("UINT16_ELEMENTS");
1014 Node* index = WordShl(intptr_index, IntPtrConstant(1)); 1016 Node* index = WordShl(intptr_index, IntPtrConstant(1));
1015 Node* element = Load(MachineType::Uint16(), backing_store, index); 1017 Node* element = Load(MachineType::Uint16(), backing_store, index);
1016 Return(SmiFromWord32(element)); 1018 exit_point->Return(SmiFromWord32(element));
1017 } 1019 }
1018 Bind(&int16_elements); 1020 Bind(&int16_elements);
1019 { 1021 {
1020 Comment("INT16_ELEMENTS"); 1022 Comment("INT16_ELEMENTS");
1021 Node* index = WordShl(intptr_index, IntPtrConstant(1)); 1023 Node* index = WordShl(intptr_index, IntPtrConstant(1));
1022 Node* element = Load(MachineType::Int16(), backing_store, index); 1024 Node* element = Load(MachineType::Int16(), backing_store, index);
1023 Return(SmiFromWord32(element)); 1025 exit_point->Return(SmiFromWord32(element));
1024 } 1026 }
1025 Bind(&uint32_elements); 1027 Bind(&uint32_elements);
1026 { 1028 {
1027 Comment("UINT32_ELEMENTS"); 1029 Comment("UINT32_ELEMENTS");
1028 Node* index = WordShl(intptr_index, IntPtrConstant(2)); 1030 Node* index = WordShl(intptr_index, IntPtrConstant(2));
1029 Node* element = Load(MachineType::Uint32(), backing_store, index); 1031 Node* element = Load(MachineType::Uint32(), backing_store, index);
1030 Return(ChangeUint32ToTagged(element)); 1032 exit_point->Return(ChangeUint32ToTagged(element));
1031 } 1033 }
1032 Bind(&int32_elements); 1034 Bind(&int32_elements);
1033 { 1035 {
1034 Comment("INT32_ELEMENTS"); 1036 Comment("INT32_ELEMENTS");
1035 Node* index = WordShl(intptr_index, IntPtrConstant(2)); 1037 Node* index = WordShl(intptr_index, IntPtrConstant(2));
1036 Node* element = Load(MachineType::Int32(), backing_store, index); 1038 Node* element = Load(MachineType::Int32(), backing_store, index);
1037 Return(ChangeInt32ToTagged(element)); 1039 exit_point->Return(ChangeInt32ToTagged(element));
1038 } 1040 }
1039 Bind(&float32_elements); 1041 Bind(&float32_elements);
1040 { 1042 {
1041 Comment("FLOAT32_ELEMENTS"); 1043 Comment("FLOAT32_ELEMENTS");
1042 Node* index = WordShl(intptr_index, IntPtrConstant(2)); 1044 Node* index = WordShl(intptr_index, IntPtrConstant(2));
1043 Node* element = Load(MachineType::Float32(), backing_store, index); 1045 Node* element = Load(MachineType::Float32(), backing_store, index);
1044 var_double_value->Bind(ChangeFloat32ToFloat64(element)); 1046 var_double_value->Bind(ChangeFloat32ToFloat64(element));
1045 Goto(rebox_double); 1047 Goto(rebox_double);
1046 } 1048 }
1047 Bind(&float64_elements); 1049 Bind(&float64_elements);
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1094 Label done(this); 1096 Label done(this);
1095 NameDictionaryLookup<NameDictionary>(properties, name, miss, &var_name_index, 1097 NameDictionaryLookup<NameDictionary>(properties, name, miss, &var_name_index,
1096 &done); 1098 &done);
1097 Bind(&done); 1099 Bind(&done);
1098 } 1100 }
1099 1101
1100 void AccessorAssembler::GenericElementLoad(Node* receiver, Node* receiver_map, 1102 void AccessorAssembler::GenericElementLoad(Node* receiver, Node* receiver_map,
1101 Node* instance_type, Node* index, 1103 Node* instance_type, Node* index,
1102 Label* slow) { 1104 Label* slow) {
1103 Comment("integer index"); 1105 Comment("integer index");
1106
1107 ExitPoint direct_exit(this);
1108
1104 Label if_element_hole(this), if_oob(this); 1109 Label if_element_hole(this), if_oob(this);
1105 // Receivers requiring non-standard element accesses (interceptors, access 1110 // Receivers requiring non-standard element accesses (interceptors, access
1106 // checks, strings and string wrappers, proxies) are handled in the runtime. 1111 // checks, strings and string wrappers, proxies) are handled in the runtime.
1107 GotoIf(Int32LessThanOrEqual(instance_type, 1112 GotoIf(Int32LessThanOrEqual(instance_type,
1108 Int32Constant(LAST_CUSTOM_ELEMENTS_RECEIVER)), 1113 Int32Constant(LAST_CUSTOM_ELEMENTS_RECEIVER)),
1109 slow); 1114 slow);
1110 Node* elements = LoadElements(receiver); 1115 Node* elements = LoadElements(receiver);
1111 Node* elements_kind = LoadMapElementsKind(receiver_map); 1116 Node* elements_kind = LoadMapElementsKind(receiver_map);
1112 Node* is_jsarray_condition = 1117 Node* is_jsarray_condition =
1113 Word32Equal(instance_type, Int32Constant(JS_ARRAY_TYPE)); 1118 Word32Equal(instance_type, Int32Constant(JS_ARRAY_TYPE));
1114 Variable var_double_value(this, MachineRepresentation::kFloat64); 1119 Variable var_double_value(this, MachineRepresentation::kFloat64);
1115 Label rebox_double(this, &var_double_value); 1120 Label rebox_double(this, &var_double_value);
1116 1121
1117 // Unimplemented elements kinds fall back to a runtime call. 1122 // Unimplemented elements kinds fall back to a runtime call.
1118 Label* unimplemented_elements_kind = slow; 1123 Label* unimplemented_elements_kind = slow;
1119 IncrementCounter(isolate()->counters()->ic_keyed_load_generic_smi(), 1); 1124 IncrementCounter(isolate()->counters()->ic_keyed_load_generic_smi(), 1);
1120 EmitElementLoad(receiver, elements, elements_kind, index, 1125 EmitElementLoad(receiver, elements, elements_kind, index,
1121 is_jsarray_condition, &if_element_hole, &rebox_double, 1126 is_jsarray_condition, &if_element_hole, &rebox_double,
1122 &var_double_value, unimplemented_elements_kind, &if_oob, 1127 &var_double_value, unimplemented_elements_kind, &if_oob, slow,
1123 slow); 1128 &direct_exit);
1124 1129
1125 Bind(&rebox_double); 1130 Bind(&rebox_double);
1126 Return(AllocateHeapNumberWithValue(var_double_value.value())); 1131 Return(AllocateHeapNumberWithValue(var_double_value.value()));
1127 1132
1128 Bind(&if_oob); 1133 Bind(&if_oob);
1129 { 1134 {
1130 Comment("out of bounds"); 1135 Comment("out of bounds");
1131 // Negative keys can't take the fast OOB path. 1136 // Negative keys can't take the fast OOB path.
1132 GotoIf(IntPtrLessThan(index, IntPtrConstant(0)), slow); 1137 GotoIf(IntPtrLessThan(index, IntPtrConstant(0)), slow);
1133 // Positive OOB indices are effectively the same as hole loads. 1138 // Positive OOB indices are effectively the same as hole loads.
(...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after
1452 } 1457 }
1453 } 1458 }
1454 1459
1455 void AccessorAssembler::LoadICProtoArray( 1460 void AccessorAssembler::LoadICProtoArray(
1456 const LoadICParameters* p, Node* handler, 1461 const LoadICParameters* p, Node* handler,
1457 bool throw_reference_error_if_nonexistent) { 1462 bool throw_reference_error_if_nonexistent) {
1458 Label miss(this); 1463 Label miss(this);
1459 CSA_ASSERT(this, Word32BinaryNot(TaggedIsSmi(handler))); 1464 CSA_ASSERT(this, Word32BinaryNot(TaggedIsSmi(handler)));
1460 CSA_ASSERT(this, IsFixedArrayMap(LoadMap(handler))); 1465 CSA_ASSERT(this, IsFixedArrayMap(LoadMap(handler)));
1461 1466
1467 ExitPoint direct_exit(this);
1468
1462 Node* smi_handler = LoadObjectField(handler, LoadHandler::kSmiHandlerOffset); 1469 Node* smi_handler = LoadObjectField(handler, LoadHandler::kSmiHandlerOffset);
1463 Node* handler_flags = SmiUntag(smi_handler); 1470 Node* handler_flags = SmiUntag(smi_handler);
1464 1471
1465 Node* handler_length = LoadAndUntagFixedArrayBaseLength(handler); 1472 Node* handler_length = LoadAndUntagFixedArrayBaseLength(handler);
1466 1473
1467 Node* holder = 1474 Node* holder =
1468 EmitLoadICProtoArrayCheck(p, handler, handler_length, handler_flags, 1475 EmitLoadICProtoArrayCheck(p, handler, handler_length, handler_flags,
1469 &miss, throw_reference_error_if_nonexistent); 1476 &miss, throw_reference_error_if_nonexistent);
1470 1477
1471 HandleLoadICSmiHandlerCase(p, holder, smi_handler, &miss, kOnlyProperties); 1478 HandleLoadICSmiHandlerCase(p, holder, smi_handler, &miss, &direct_exit,
1479 kOnlyProperties);
1472 1480
1473 Bind(&miss); 1481 Bind(&miss);
1474 { 1482 {
1475 TailCallRuntime(Runtime::kLoadIC_Miss, p->context, p->receiver, p->name, 1483 TailCallRuntime(Runtime::kLoadIC_Miss, p->context, p->receiver, p->name,
1476 p->slot, p->vector); 1484 p->slot, p->vector);
1477 } 1485 }
1478 } 1486 }
1479 1487
1480 void AccessorAssembler::LoadGlobalIC(const LoadICParameters* p, 1488 void AccessorAssembler::LoadGlobalICData(const LoadICParameters* p,
Igor Sheludko 2017/02/08 15:26:31 LoadGlobalIC_TryPropertyCellCase(Node* vector, Nod
jgruber 2017/02/09 09:23:42 SG. I had it like this in an upcoming CL to omit u
1481 TypeofMode typeof_mode) { 1489 ExitPoint* exit_point,
1482 Label try_handler(this), call_handler(this), miss(this); 1490 Label* try_handler, Label* miss) {
1491 Comment("LoadGlobalICData");
Igor Sheludko 2017/02/08 15:26:31 Same here.
jgruber 2017/02/09 09:23:42 Done.
1492
1483 Node* weak_cell = 1493 Node* weak_cell =
1484 LoadFixedArrayElement(p->vector, p->slot, 0, SMI_PARAMETERS); 1494 LoadFixedArrayElement(p->vector, p->slot, 0, SMI_PARAMETERS);
1485 CSA_ASSERT(this, HasInstanceType(weak_cell, WEAK_CELL_TYPE)); 1495 CSA_ASSERT(this, HasInstanceType(weak_cell, WEAK_CELL_TYPE));
1486 1496
1487 // Load value or try handler case if the {weak_cell} is cleared. 1497 // Load value or try handler case if the {weak_cell} is cleared.
1488 Node* property_cell = LoadWeakCellValue(weak_cell, &try_handler); 1498 Node* property_cell = LoadWeakCellValue(weak_cell, try_handler);
1489 CSA_ASSERT(this, HasInstanceType(property_cell, PROPERTY_CELL_TYPE)); 1499 CSA_ASSERT(this, HasInstanceType(property_cell, PROPERTY_CELL_TYPE));
1490 1500
1491 Node* value = LoadObjectField(property_cell, PropertyCell::kValueOffset); 1501 Node* value = LoadObjectField(property_cell, PropertyCell::kValueOffset);
1492 GotoIf(WordEqual(value, TheHoleConstant()), &miss); 1502 GotoIf(WordEqual(value, TheHoleConstant()), miss);
1493 Return(value); 1503 exit_point->Return(value);
1504 }
1494 1505
1495 Node* handler; 1506 void AccessorAssembler::LoadGlobalICHandler(const LoadICParameters* p,
Igor Sheludko 2017/02/08 15:26:31 LoadGlobalIC_TryHandlerCase
jgruber 2017/02/09 09:23:42 Done.
1496 Bind(&try_handler); 1507 TypeofMode typeof_mode,
1497 { 1508 ExitPoint* exit_point,
1498 handler = 1509 Label* miss) {
1499 LoadFixedArrayElement(p->vector, p->slot, kPointerSize, SMI_PARAMETERS); 1510 Comment("LoadGlobalICHandler");
Igor Sheludko 2017/02/08 15:26:31 Same here.
jgruber 2017/02/09 09:23:42 Done.
1500 CSA_ASSERT(this, Word32BinaryNot(TaggedIsSmi(handler)));
1501 GotoIf(WordEqual(handler, LoadRoot(Heap::kuninitialized_symbolRootIndex)),
1502 &miss);
1503 GotoIf(IsCodeMap(LoadMap(handler)), &call_handler);
1504 1511
1505 bool throw_reference_error_if_nonexistent = 1512 Label call_handler(this);
1506 typeof_mode == NOT_INSIDE_TYPEOF; 1513
1507 HandleLoadGlobalICHandlerCase(p, handler, &miss, 1514 Node* handler =
1508 throw_reference_error_if_nonexistent); 1515 LoadFixedArrayElement(p->vector, p->slot, kPointerSize, SMI_PARAMETERS);
1509 } 1516 CSA_ASSERT(this, Word32BinaryNot(TaggedIsSmi(handler)));
1517 GotoIf(WordEqual(handler, LoadRoot(Heap::kuninitialized_symbolRootIndex)),
1518 miss);
1519 GotoIf(IsCodeMap(LoadMap(handler)), &call_handler);
1520
1521 bool throw_reference_error_if_nonexistent = typeof_mode == NOT_INSIDE_TYPEOF;
1522 HandleLoadGlobalICHandlerCase(p, handler, miss, exit_point,
1523 throw_reference_error_if_nonexistent);
1510 1524
1511 Bind(&call_handler); 1525 Bind(&call_handler);
1512 { 1526 {
1513 LoadWithVectorDescriptor descriptor(isolate()); 1527 LoadWithVectorDescriptor descriptor(isolate());
1514 Node* native_context = LoadNativeContext(p->context); 1528 Node* native_context = LoadNativeContext(p->context);
1515 Node* receiver = 1529 Node* receiver =
1516 LoadContextElement(native_context, Context::EXTENSION_INDEX); 1530 LoadContextElement(native_context, Context::EXTENSION_INDEX);
1517 TailCallStub(descriptor, handler, p->context, receiver, p->name, p->slot, 1531 exit_point->ReturnStub(descriptor, handler, p->context, receiver, p->name,
1518 p->vector); 1532 p->slot, p->vector);
1519 }
1520 Bind(&miss);
1521 {
1522 TailCallRuntime(Runtime::kLoadGlobalIC_Miss, p->context, p->name, p->slot,
1523 p->vector);
1524 } 1533 }
1525 } 1534 }
1526 1535
1536 void AccessorAssembler::LoadGlobalICMiss(const LoadICParameters* p,
1537 ExitPoint* exit_point) {
1538 Comment("LoadGlobalICMiss");
1539
1540 exit_point->ReturnRuntime(Runtime::kLoadGlobalIC_Miss, p->context, p->name,
1541 p->slot, p->vector);
1542 }
1543
1544 void AccessorAssembler::LoadGlobalIC(const LoadICParameters* p,
1545 TypeofMode typeof_mode) {
1546 ExitPoint direct_exit(this);
1547
1548 Label try_handler(this), miss(this);
1549 LoadGlobalICData(p, &direct_exit, &try_handler, &miss);
1550
1551 Bind(&try_handler);
1552 LoadGlobalICHandler(p, typeof_mode, &direct_exit, &miss);
1553
1554 Bind(&miss);
1555 LoadGlobalICMiss(p, &direct_exit);
1556 }
1557
1527 void AccessorAssembler::KeyedLoadIC(const LoadICParameters* p) { 1558 void AccessorAssembler::KeyedLoadIC(const LoadICParameters* p) {
1528 Variable var_handler(this, MachineRepresentation::kTagged); 1559 Variable var_handler(this, MachineRepresentation::kTagged);
1529 // TODO(ishell): defer blocks when it works. 1560 // TODO(ishell): defer blocks when it works.
1530 Label if_handler(this, &var_handler), try_polymorphic(this), 1561 Label if_handler(this, &var_handler), try_polymorphic(this),
1531 try_megamorphic(this /*, Label::kDeferred*/), 1562 try_megamorphic(this /*, Label::kDeferred*/),
1532 try_polymorphic_name(this /*, Label::kDeferred*/), 1563 try_polymorphic_name(this /*, Label::kDeferred*/),
1533 miss(this /*, Label::kDeferred*/); 1564 miss(this /*, Label::kDeferred*/);
1534 1565
1535 Node* receiver_map = LoadReceiverMap(p->receiver); 1566 Node* receiver_map = LoadReceiverMap(p->receiver);
1536 1567
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after
1822 void AccessorAssembler::GenerateLoadField() { 1853 void AccessorAssembler::GenerateLoadField() {
1823 typedef LoadFieldDescriptor Descriptor; 1854 typedef LoadFieldDescriptor Descriptor;
1824 1855
1825 Node* receiver = Parameter(Descriptor::kReceiver); 1856 Node* receiver = Parameter(Descriptor::kReceiver);
1826 Node* name = nullptr; 1857 Node* name = nullptr;
1827 Node* slot = nullptr; 1858 Node* slot = nullptr;
1828 Node* vector = nullptr; 1859 Node* vector = nullptr;
1829 Node* context = Parameter(Descriptor::kContext); 1860 Node* context = Parameter(Descriptor::kContext);
1830 LoadICParameters p(context, receiver, name, slot, vector); 1861 LoadICParameters p(context, receiver, name, slot, vector);
1831 1862
1863 ExitPoint direct_exit(this);
1864
1832 HandleLoadICSmiHandlerCase(&p, receiver, Parameter(Descriptor::kSmiHandler), 1865 HandleLoadICSmiHandlerCase(&p, receiver, Parameter(Descriptor::kSmiHandler),
1833 nullptr, kOnlyProperties); 1866 nullptr, &direct_exit, kOnlyProperties);
1834 } 1867 }
1835 1868
1836 void AccessorAssembler::GenerateLoadGlobalIC(TypeofMode typeof_mode) { 1869 void AccessorAssembler::GenerateLoadGlobalIC(TypeofMode typeof_mode) {
1837 typedef LoadGlobalWithVectorDescriptor Descriptor; 1870 typedef LoadGlobalWithVectorDescriptor Descriptor;
1838 1871
1839 Node* name = Parameter(Descriptor::kName); 1872 Node* name = Parameter(Descriptor::kName);
1840 Node* slot = Parameter(Descriptor::kSlot); 1873 Node* slot = Parameter(Descriptor::kSlot);
1841 Node* vector = Parameter(Descriptor::kVector); 1874 Node* vector = Parameter(Descriptor::kVector);
1842 Node* context = Parameter(Descriptor::kContext); 1875 Node* context = Parameter(Descriptor::kContext);
1843 1876
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
1948 Node* slot = Parameter(Descriptor::kSlot); 1981 Node* slot = Parameter(Descriptor::kSlot);
1949 Node* context = Parameter(Descriptor::kContext); 1982 Node* context = Parameter(Descriptor::kContext);
1950 Node* vector = LoadFeedbackVectorForStub(); 1983 Node* vector = LoadFeedbackVectorForStub();
1951 1984
1952 StoreICParameters p(context, receiver, name, value, slot, vector); 1985 StoreICParameters p(context, receiver, name, value, slot, vector);
1953 KeyedStoreIC(&p, language_mode); 1986 KeyedStoreIC(&p, language_mode);
1954 } 1987 }
1955 1988
1956 } // namespace internal 1989 } // namespace internal
1957 } // namespace v8 1990 } // namespace v8
OLDNEW
« src/ic/accessor-assembler.h ('K') | « src/ic/accessor-assembler.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698