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

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

Issue 2688503002: [ic] Refactor LoadGlobalIC in preparation for handler inlining (Closed)
Patch Set: Address comments 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
« no previous file with comments | « 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->ReturnCallStub(callable, p->context, p->receiver, holder,
299 value);
297 } 300 }
298 } 301 }
299 302
300 void AccessorAssembler::HandleLoadICProtoHandlerCase( 303 void AccessorAssembler::HandleLoadICProtoHandlerCase(
301 const LoadICParameters* p, Node* handler, Variable* var_holder, 304 const LoadICParameters* p, Node* handler, Variable* var_holder,
302 Variable* var_smi_handler, Label* if_smi_handler, Label* miss, 305 Variable* var_smi_handler, Label* if_smi_handler, Label* miss,
303 bool throw_reference_error_if_nonexistent) { 306 ExitPoint* exit_point, bool throw_reference_error_if_nonexistent) {
304 DCHECK_EQ(MachineRepresentation::kTagged, var_holder->rep()); 307 DCHECK_EQ(MachineRepresentation::kTagged, var_holder->rep());
305 DCHECK_EQ(MachineRepresentation::kTagged, var_smi_handler->rep()); 308 DCHECK_EQ(MachineRepresentation::kTagged, var_smi_handler->rep());
306 309
307 // IC dispatchers rely on these assumptions to be held. 310 // IC dispatchers rely on these assumptions to be held.
308 STATIC_ASSERT(FixedArray::kLengthOffset == LoadHandler::kHolderCellOffset); 311 STATIC_ASSERT(FixedArray::kLengthOffset == LoadHandler::kHolderCellOffset);
309 DCHECK_EQ(FixedArray::OffsetOfElementAt(LoadHandler::kSmiHandlerIndex), 312 DCHECK_EQ(FixedArray::OffsetOfElementAt(LoadHandler::kSmiHandlerIndex),
310 LoadHandler::kSmiHandlerOffset); 313 LoadHandler::kSmiHandlerOffset);
311 DCHECK_EQ(FixedArray::OffsetOfElementAt(LoadHandler::kValidityCellIndex), 314 DCHECK_EQ(FixedArray::OffsetOfElementAt(LoadHandler::kValidityCellIndex),
312 LoadHandler::kValidityCellOffset); 315 LoadHandler::kValidityCellOffset);
313 316
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
345 LoadObjectField(handler, LoadHandler::kHolderCellOffset); 348 LoadObjectField(handler, LoadHandler::kHolderCellOffset);
346 Label array_handler(this), tuple_handler(this); 349 Label array_handler(this), tuple_handler(this);
347 Branch(TaggedIsSmi(maybe_holder_cell), &array_handler, &tuple_handler); 350 Branch(TaggedIsSmi(maybe_holder_cell), &array_handler, &tuple_handler);
348 351
349 Bind(&tuple_handler); 352 Bind(&tuple_handler);
350 { 353 {
351 Label load_existent(this); 354 Label load_existent(this);
352 GotoIf(WordNotEqual(maybe_holder_cell, NullConstant()), &load_existent); 355 GotoIf(WordNotEqual(maybe_holder_cell, NullConstant()), &load_existent);
353 // This is a handler for a load of a non-existent value. 356 // This is a handler for a load of a non-existent value.
354 if (throw_reference_error_if_nonexistent) { 357 if (throw_reference_error_if_nonexistent) {
355 TailCallRuntime(Runtime::kThrowReferenceError, p->context, p->name); 358 exit_point->ReturnCallRuntime(Runtime::kThrowReferenceError, p->context,
359 p->name);
356 } else { 360 } else {
357 Return(UndefinedConstant()); 361 exit_point->Return(UndefinedConstant());
358 } 362 }
359 363
360 Bind(&load_existent); 364 Bind(&load_existent);
361 Node* holder = LoadWeakCellValue(maybe_holder_cell); 365 Node* holder = LoadWeakCellValue(maybe_holder_cell);
362 // The |holder| is guaranteed to be alive at this point since we passed 366 // The |holder| is guaranteed to be alive at this point since we passed
363 // both the receiver map check and the validity cell check. 367 // both the receiver map check and the validity cell check.
364 CSA_ASSERT(this, WordNotEqual(holder, IntPtrConstant(0))); 368 CSA_ASSERT(this, WordNotEqual(holder, IntPtrConstant(0)));
365 369
366 var_holder->Bind(holder); 370 var_holder->Bind(holder);
367 var_smi_handler->Bind(smi_handler); 371 var_smi_handler->Bind(smi_handler);
368 Goto(if_smi_handler); 372 Goto(if_smi_handler);
369 } 373 }
370 374
371 Bind(&array_handler); 375 Bind(&array_handler);
372 { 376 {
373 TailCallStub(CodeFactory::LoadICProtoArray( 377 exit_point->ReturnCallStub(
374 isolate(), throw_reference_error_if_nonexistent), 378 CodeFactory::LoadICProtoArray(isolate(),
375 p->context, p->receiver, p->name, p->slot, p->vector, handler); 379 throw_reference_error_if_nonexistent),
380 p->context, p->receiver, p->name, p->slot, p->vector, handler);
376 } 381 }
377 } 382 }
378 383
379 Node* AccessorAssembler::EmitLoadICProtoArrayCheck( 384 Node* AccessorAssembler::EmitLoadICProtoArrayCheck(
380 const LoadICParameters* p, Node* handler, Node* handler_length, 385 const LoadICParameters* p, Node* handler, Node* handler_length,
381 Node* handler_flags, Label* miss, 386 Node* handler_flags, Label* miss,
382 bool throw_reference_error_if_nonexistent) { 387 bool throw_reference_error_if_nonexistent) {
383 Variable start_index(this, MachineType::PointerRepresentation()); 388 Variable start_index(this, MachineType::PointerRepresentation());
384 start_index.Bind(IntPtrConstant(LoadHandler::kFirstPrototypeIndex)); 389 start_index.Bind(IntPtrConstant(LoadHandler::kFirstPrototypeIndex));
385 390
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
433 Node* holder = LoadWeakCellValue(maybe_holder_cell); 438 Node* holder = LoadWeakCellValue(maybe_holder_cell);
434 // The |holder| is guaranteed to be alive at this point since we passed 439 // 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 440 // the receiver map check, the validity cell check and the prototype chain
436 // check. 441 // check.
437 CSA_ASSERT(this, WordNotEqual(holder, IntPtrConstant(0))); 442 CSA_ASSERT(this, WordNotEqual(holder, IntPtrConstant(0)));
438 return holder; 443 return holder;
439 } 444 }
440 445
441 void AccessorAssembler::HandleLoadGlobalICHandlerCase( 446 void AccessorAssembler::HandleLoadGlobalICHandlerCase(
442 const LoadICParameters* pp, Node* handler, Label* miss, 447 const LoadICParameters* pp, Node* handler, Label* miss,
443 bool throw_reference_error_if_nonexistent) { 448 ExitPoint* exit_point, bool throw_reference_error_if_nonexistent) {
444 LoadICParameters p = *pp; 449 LoadICParameters p = *pp;
445 DCHECK_NULL(p.receiver); 450 DCHECK_NULL(p.receiver);
446 Node* native_context = LoadNativeContext(p.context); 451 Node* native_context = LoadNativeContext(p.context);
447 p.receiver = LoadContextElement(native_context, Context::EXTENSION_INDEX); 452 p.receiver = LoadContextElement(native_context, Context::EXTENSION_INDEX);
448 453
449 Variable var_holder(this, MachineRepresentation::kTagged); 454 Variable var_holder(this, MachineRepresentation::kTagged);
450 Variable var_smi_handler(this, MachineRepresentation::kTagged); 455 Variable var_smi_handler(this, MachineRepresentation::kTagged);
451 Label if_smi_handler(this); 456 Label if_smi_handler(this);
452 HandleLoadICProtoHandlerCase(&p, handler, &var_holder, &var_smi_handler, 457 HandleLoadICProtoHandlerCase(&p, handler, &var_holder, &var_smi_handler,
453 &if_smi_handler, miss, 458 &if_smi_handler, miss, exit_point,
454 throw_reference_error_if_nonexistent); 459 throw_reference_error_if_nonexistent);
455 Bind(&if_smi_handler); 460 Bind(&if_smi_handler);
456 HandleLoadICSmiHandlerCase(&p, var_holder.value(), var_smi_handler.value(), 461 HandleLoadICSmiHandlerCase(&p, var_holder.value(), var_smi_handler.value(),
457 miss, kOnlyProperties); 462 miss, exit_point, kOnlyProperties);
458 } 463 }
459 464
460 void AccessorAssembler::HandleStoreICHandlerCase( 465 void AccessorAssembler::HandleStoreICHandlerCase(
461 const StoreICParameters* p, Node* handler, Label* miss, 466 const StoreICParameters* p, Node* handler, Label* miss,
462 ElementSupport support_elements) { 467 ElementSupport support_elements) {
463 Label if_smi_handler(this), if_nonsmi_handler(this); 468 Label if_smi_handler(this), if_nonsmi_handler(this);
464 Label if_proto_handler(this), if_element_handler(this), call_handler(this); 469 Label if_proto_handler(this), if_element_handler(this), call_handler(this);
465 470
466 Branch(TaggedIsSmi(handler), &if_smi_handler, &if_nonsmi_handler); 471 Branch(TaggedIsSmi(handler), &if_smi_handler, &if_nonsmi_handler);
467 472
(...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after
849 } 854 }
850 Bind(&if_array); 855 Bind(&if_array);
851 { 856 {
852 var_length.Bind(SmiUntag(LoadJSArrayLength(object))); 857 var_length.Bind(SmiUntag(LoadJSArrayLength(object)));
853 Goto(&length_loaded); 858 Goto(&length_loaded);
854 } 859 }
855 Bind(&length_loaded); 860 Bind(&length_loaded);
856 GotoUnless(UintPtrLessThan(intptr_index, var_length.value()), miss); 861 GotoUnless(UintPtrLessThan(intptr_index, var_length.value()), miss);
857 } 862 }
858 863
859 void AccessorAssembler::EmitElementLoad(Node* object, Node* elements, 864 void AccessorAssembler::EmitElementLoad(
860 Node* elements_kind, Node* intptr_index, 865 Node* object, Node* elements, Node* elements_kind, Node* intptr_index,
861 Node* is_jsarray_condition, 866 Node* is_jsarray_condition, Label* if_hole, Label* rebox_double,
862 Label* if_hole, Label* rebox_double, 867 Variable* var_double_value, Label* unimplemented_elements_kind,
863 Variable* var_double_value, 868 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), 869 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), 870 if_fast_double(this), if_fast_holey_double(this), if_nonfast(this),
868 if_dictionary(this); 871 if_dictionary(this);
869 GotoIf( 872 GotoIf(
870 Int32GreaterThan(elements_kind, Int32Constant(LAST_FAST_ELEMENTS_KIND)), 873 Int32GreaterThan(elements_kind, Int32Constant(LAST_FAST_ELEMENTS_KIND)),
871 &if_nonfast); 874 &if_nonfast);
872 875
873 EmitFastElementsBoundsCheck(object, elements, intptr_index, 876 EmitFastElementsBoundsCheck(object, elements, intptr_index,
874 is_jsarray_condition, out_of_bounds); 877 is_jsarray_condition, out_of_bounds);
875 int32_t kinds[] = {// Handled by if_fast_packed. 878 int32_t kinds[] = {// Handled by if_fast_packed.
(...skipping 11 matching lines...) Expand all
887 // FAST_DOUBLE_ELEMENTS 890 // FAST_DOUBLE_ELEMENTS
888 &if_fast_double, 891 &if_fast_double,
889 // FAST_HOLEY_DOUBLE_ELEMENTS 892 // FAST_HOLEY_DOUBLE_ELEMENTS
890 &if_fast_holey_double}; 893 &if_fast_holey_double};
891 Switch(elements_kind, unimplemented_elements_kind, kinds, labels, 894 Switch(elements_kind, unimplemented_elements_kind, kinds, labels,
892 arraysize(kinds)); 895 arraysize(kinds));
893 896
894 Bind(&if_fast_packed); 897 Bind(&if_fast_packed);
895 { 898 {
896 Comment("fast packed elements"); 899 Comment("fast packed elements");
897 Return(LoadFixedArrayElement(elements, intptr_index)); 900 exit_point->Return(LoadFixedArrayElement(elements, intptr_index));
898 } 901 }
899 902
900 Bind(&if_fast_holey); 903 Bind(&if_fast_holey);
901 { 904 {
902 Comment("fast holey elements"); 905 Comment("fast holey elements");
903 Node* element = LoadFixedArrayElement(elements, intptr_index); 906 Node* element = LoadFixedArrayElement(elements, intptr_index);
904 GotoIf(WordEqual(element, TheHoleConstant()), if_hole); 907 GotoIf(WordEqual(element, TheHoleConstant()), if_hole);
905 Return(element); 908 exit_point->Return(element);
906 } 909 }
907 910
908 Bind(&if_fast_double); 911 Bind(&if_fast_double);
909 { 912 {
910 Comment("packed double elements"); 913 Comment("packed double elements");
911 var_double_value->Bind(LoadFixedDoubleArrayElement(elements, intptr_index, 914 var_double_value->Bind(LoadFixedDoubleArrayElement(elements, intptr_index,
912 MachineType::Float64())); 915 MachineType::Float64()));
913 Goto(rebox_double); 916 Goto(rebox_double);
914 } 917 }
915 918
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
947 // Check that the value is a data property. 950 // Check that the value is a data property.
948 Node* details_index = EntryToIndex<SeededNumberDictionary>( 951 Node* details_index = EntryToIndex<SeededNumberDictionary>(
949 var_entry.value(), SeededNumberDictionary::kEntryDetailsIndex); 952 var_entry.value(), SeededNumberDictionary::kEntryDetailsIndex);
950 Node* details = SmiToWord32(LoadFixedArrayElement(elements, details_index)); 953 Node* details = SmiToWord32(LoadFixedArrayElement(elements, details_index));
951 Node* kind = DecodeWord32<PropertyDetails::KindField>(details); 954 Node* kind = DecodeWord32<PropertyDetails::KindField>(details);
952 // TODO(jkummerow): Support accessors without missing? 955 // TODO(jkummerow): Support accessors without missing?
953 GotoUnless(Word32Equal(kind, Int32Constant(kData)), miss); 956 GotoUnless(Word32Equal(kind, Int32Constant(kData)), miss);
954 // Finally, load the value. 957 // Finally, load the value.
955 Node* value_index = EntryToIndex<SeededNumberDictionary>( 958 Node* value_index = EntryToIndex<SeededNumberDictionary>(
956 var_entry.value(), SeededNumberDictionary::kEntryValueIndex); 959 var_entry.value(), SeededNumberDictionary::kEntryValueIndex);
957 Return(LoadFixedArrayElement(elements, value_index)); 960 exit_point->Return(LoadFixedArrayElement(elements, value_index));
958 } 961 }
959 962
960 Bind(&if_typed_array); 963 Bind(&if_typed_array);
961 { 964 {
962 Comment("typed elements"); 965 Comment("typed elements");
963 // Check if buffer has been neutered. 966 // Check if buffer has been neutered.
964 Node* buffer = LoadObjectField(object, JSArrayBufferView::kBufferOffset); 967 Node* buffer = LoadObjectField(object, JSArrayBufferView::kBufferOffset);
965 GotoIf(IsDetachedBuffer(buffer), miss); 968 GotoIf(IsDetachedBuffer(buffer), miss);
966 969
967 // Bounds check. 970 // Bounds check.
(...skipping 25 matching lines...) Expand all
993 LAST_FIXED_TYPED_ARRAY_ELEMENTS_KIND - 996 LAST_FIXED_TYPED_ARRAY_ELEMENTS_KIND -
994 FIRST_FIXED_TYPED_ARRAY_ELEMENTS_KIND + 1; 997 FIRST_FIXED_TYPED_ARRAY_ELEMENTS_KIND + 1;
995 DCHECK_EQ(kTypedElementsKindCount, arraysize(elements_kinds)); 998 DCHECK_EQ(kTypedElementsKindCount, arraysize(elements_kinds));
996 DCHECK_EQ(kTypedElementsKindCount, arraysize(elements_kind_labels)); 999 DCHECK_EQ(kTypedElementsKindCount, arraysize(elements_kind_labels));
997 Switch(elements_kind, miss, elements_kinds, elements_kind_labels, 1000 Switch(elements_kind, miss, elements_kinds, elements_kind_labels,
998 kTypedElementsKindCount); 1001 kTypedElementsKindCount);
999 Bind(&uint8_elements); 1002 Bind(&uint8_elements);
1000 { 1003 {
1001 Comment("UINT8_ELEMENTS"); // Handles UINT8_CLAMPED_ELEMENTS too. 1004 Comment("UINT8_ELEMENTS"); // Handles UINT8_CLAMPED_ELEMENTS too.
1002 Node* element = Load(MachineType::Uint8(), backing_store, intptr_index); 1005 Node* element = Load(MachineType::Uint8(), backing_store, intptr_index);
1003 Return(SmiFromWord32(element)); 1006 exit_point->Return(SmiFromWord32(element));
1004 } 1007 }
1005 Bind(&int8_elements); 1008 Bind(&int8_elements);
1006 { 1009 {
1007 Comment("INT8_ELEMENTS"); 1010 Comment("INT8_ELEMENTS");
1008 Node* element = Load(MachineType::Int8(), backing_store, intptr_index); 1011 Node* element = Load(MachineType::Int8(), backing_store, intptr_index);
1009 Return(SmiFromWord32(element)); 1012 exit_point->Return(SmiFromWord32(element));
1010 } 1013 }
1011 Bind(&uint16_elements); 1014 Bind(&uint16_elements);
1012 { 1015 {
1013 Comment("UINT16_ELEMENTS"); 1016 Comment("UINT16_ELEMENTS");
1014 Node* index = WordShl(intptr_index, IntPtrConstant(1)); 1017 Node* index = WordShl(intptr_index, IntPtrConstant(1));
1015 Node* element = Load(MachineType::Uint16(), backing_store, index); 1018 Node* element = Load(MachineType::Uint16(), backing_store, index);
1016 Return(SmiFromWord32(element)); 1019 exit_point->Return(SmiFromWord32(element));
1017 } 1020 }
1018 Bind(&int16_elements); 1021 Bind(&int16_elements);
1019 { 1022 {
1020 Comment("INT16_ELEMENTS"); 1023 Comment("INT16_ELEMENTS");
1021 Node* index = WordShl(intptr_index, IntPtrConstant(1)); 1024 Node* index = WordShl(intptr_index, IntPtrConstant(1));
1022 Node* element = Load(MachineType::Int16(), backing_store, index); 1025 Node* element = Load(MachineType::Int16(), backing_store, index);
1023 Return(SmiFromWord32(element)); 1026 exit_point->Return(SmiFromWord32(element));
1024 } 1027 }
1025 Bind(&uint32_elements); 1028 Bind(&uint32_elements);
1026 { 1029 {
1027 Comment("UINT32_ELEMENTS"); 1030 Comment("UINT32_ELEMENTS");
1028 Node* index = WordShl(intptr_index, IntPtrConstant(2)); 1031 Node* index = WordShl(intptr_index, IntPtrConstant(2));
1029 Node* element = Load(MachineType::Uint32(), backing_store, index); 1032 Node* element = Load(MachineType::Uint32(), backing_store, index);
1030 Return(ChangeUint32ToTagged(element)); 1033 exit_point->Return(ChangeUint32ToTagged(element));
1031 } 1034 }
1032 Bind(&int32_elements); 1035 Bind(&int32_elements);
1033 { 1036 {
1034 Comment("INT32_ELEMENTS"); 1037 Comment("INT32_ELEMENTS");
1035 Node* index = WordShl(intptr_index, IntPtrConstant(2)); 1038 Node* index = WordShl(intptr_index, IntPtrConstant(2));
1036 Node* element = Load(MachineType::Int32(), backing_store, index); 1039 Node* element = Load(MachineType::Int32(), backing_store, index);
1037 Return(ChangeInt32ToTagged(element)); 1040 exit_point->Return(ChangeInt32ToTagged(element));
1038 } 1041 }
1039 Bind(&float32_elements); 1042 Bind(&float32_elements);
1040 { 1043 {
1041 Comment("FLOAT32_ELEMENTS"); 1044 Comment("FLOAT32_ELEMENTS");
1042 Node* index = WordShl(intptr_index, IntPtrConstant(2)); 1045 Node* index = WordShl(intptr_index, IntPtrConstant(2));
1043 Node* element = Load(MachineType::Float32(), backing_store, index); 1046 Node* element = Load(MachineType::Float32(), backing_store, index);
1044 var_double_value->Bind(ChangeFloat32ToFloat64(element)); 1047 var_double_value->Bind(ChangeFloat32ToFloat64(element));
1045 Goto(rebox_double); 1048 Goto(rebox_double);
1046 } 1049 }
1047 Bind(&float64_elements); 1050 Bind(&float64_elements);
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1094 Label done(this); 1097 Label done(this);
1095 NameDictionaryLookup<NameDictionary>(properties, name, miss, &var_name_index, 1098 NameDictionaryLookup<NameDictionary>(properties, name, miss, &var_name_index,
1096 &done); 1099 &done);
1097 Bind(&done); 1100 Bind(&done);
1098 } 1101 }
1099 1102
1100 void AccessorAssembler::GenericElementLoad(Node* receiver, Node* receiver_map, 1103 void AccessorAssembler::GenericElementLoad(Node* receiver, Node* receiver_map,
1101 Node* instance_type, Node* index, 1104 Node* instance_type, Node* index,
1102 Label* slow) { 1105 Label* slow) {
1103 Comment("integer index"); 1106 Comment("integer index");
1107
1108 ExitPoint direct_exit(this);
1109
1104 Label if_element_hole(this), if_oob(this); 1110 Label if_element_hole(this), if_oob(this);
1105 // Receivers requiring non-standard element accesses (interceptors, access 1111 // Receivers requiring non-standard element accesses (interceptors, access
1106 // checks, strings and string wrappers, proxies) are handled in the runtime. 1112 // checks, strings and string wrappers, proxies) are handled in the runtime.
1107 GotoIf(Int32LessThanOrEqual(instance_type, 1113 GotoIf(Int32LessThanOrEqual(instance_type,
1108 Int32Constant(LAST_CUSTOM_ELEMENTS_RECEIVER)), 1114 Int32Constant(LAST_CUSTOM_ELEMENTS_RECEIVER)),
1109 slow); 1115 slow);
1110 Node* elements = LoadElements(receiver); 1116 Node* elements = LoadElements(receiver);
1111 Node* elements_kind = LoadMapElementsKind(receiver_map); 1117 Node* elements_kind = LoadMapElementsKind(receiver_map);
1112 Node* is_jsarray_condition = 1118 Node* is_jsarray_condition =
1113 Word32Equal(instance_type, Int32Constant(JS_ARRAY_TYPE)); 1119 Word32Equal(instance_type, Int32Constant(JS_ARRAY_TYPE));
1114 Variable var_double_value(this, MachineRepresentation::kFloat64); 1120 Variable var_double_value(this, MachineRepresentation::kFloat64);
1115 Label rebox_double(this, &var_double_value); 1121 Label rebox_double(this, &var_double_value);
1116 1122
1117 // Unimplemented elements kinds fall back to a runtime call. 1123 // Unimplemented elements kinds fall back to a runtime call.
1118 Label* unimplemented_elements_kind = slow; 1124 Label* unimplemented_elements_kind = slow;
1119 IncrementCounter(isolate()->counters()->ic_keyed_load_generic_smi(), 1); 1125 IncrementCounter(isolate()->counters()->ic_keyed_load_generic_smi(), 1);
1120 EmitElementLoad(receiver, elements, elements_kind, index, 1126 EmitElementLoad(receiver, elements, elements_kind, index,
1121 is_jsarray_condition, &if_element_hole, &rebox_double, 1127 is_jsarray_condition, &if_element_hole, &rebox_double,
1122 &var_double_value, unimplemented_elements_kind, &if_oob, 1128 &var_double_value, unimplemented_elements_kind, &if_oob, slow,
1123 slow); 1129 &direct_exit);
1124 1130
1125 Bind(&rebox_double); 1131 Bind(&rebox_double);
1126 Return(AllocateHeapNumberWithValue(var_double_value.value())); 1132 Return(AllocateHeapNumberWithValue(var_double_value.value()));
1127 1133
1128 Bind(&if_oob); 1134 Bind(&if_oob);
1129 { 1135 {
1130 Comment("out of bounds"); 1136 Comment("out of bounds");
1131 // Negative keys can't take the fast OOB path. 1137 // Negative keys can't take the fast OOB path.
1132 GotoIf(IntPtrLessThan(index, IntPtrConstant(0)), slow); 1138 GotoIf(IntPtrLessThan(index, IntPtrConstant(0)), slow);
1133 // Positive OOB indices are effectively the same as hole loads. 1139 // Positive OOB indices are effectively the same as hole loads.
(...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after
1452 } 1458 }
1453 } 1459 }
1454 1460
1455 void AccessorAssembler::LoadICProtoArray( 1461 void AccessorAssembler::LoadICProtoArray(
1456 const LoadICParameters* p, Node* handler, 1462 const LoadICParameters* p, Node* handler,
1457 bool throw_reference_error_if_nonexistent) { 1463 bool throw_reference_error_if_nonexistent) {
1458 Label miss(this); 1464 Label miss(this);
1459 CSA_ASSERT(this, Word32BinaryNot(TaggedIsSmi(handler))); 1465 CSA_ASSERT(this, Word32BinaryNot(TaggedIsSmi(handler)));
1460 CSA_ASSERT(this, IsFixedArrayMap(LoadMap(handler))); 1466 CSA_ASSERT(this, IsFixedArrayMap(LoadMap(handler)));
1461 1467
1468 ExitPoint direct_exit(this);
1469
1462 Node* smi_handler = LoadObjectField(handler, LoadHandler::kSmiHandlerOffset); 1470 Node* smi_handler = LoadObjectField(handler, LoadHandler::kSmiHandlerOffset);
1463 Node* handler_flags = SmiUntag(smi_handler); 1471 Node* handler_flags = SmiUntag(smi_handler);
1464 1472
1465 Node* handler_length = LoadAndUntagFixedArrayBaseLength(handler); 1473 Node* handler_length = LoadAndUntagFixedArrayBaseLength(handler);
1466 1474
1467 Node* holder = 1475 Node* holder =
1468 EmitLoadICProtoArrayCheck(p, handler, handler_length, handler_flags, 1476 EmitLoadICProtoArrayCheck(p, handler, handler_length, handler_flags,
1469 &miss, throw_reference_error_if_nonexistent); 1477 &miss, throw_reference_error_if_nonexistent);
1470 1478
1471 HandleLoadICSmiHandlerCase(p, holder, smi_handler, &miss, kOnlyProperties); 1479 HandleLoadICSmiHandlerCase(p, holder, smi_handler, &miss, &direct_exit,
1480 kOnlyProperties);
1472 1481
1473 Bind(&miss); 1482 Bind(&miss);
1474 { 1483 {
1475 TailCallRuntime(Runtime::kLoadIC_Miss, p->context, p->receiver, p->name, 1484 TailCallRuntime(Runtime::kLoadIC_Miss, p->context, p->receiver, p->name,
1476 p->slot, p->vector); 1485 p->slot, p->vector);
1477 } 1486 }
1478 } 1487 }
1479 1488
1480 void AccessorAssembler::LoadGlobalIC(const LoadICParameters* p, 1489 void AccessorAssembler::LoadGlobalIC_TryPropertyCellCase(
1481 TypeofMode typeof_mode) { 1490 Node* vector, Node* slot, ExitPoint* exit_point, Label* try_handler,
1482 Label try_handler(this), call_handler(this), miss(this); 1491 Label* miss, ParameterMode slot_mode) {
1483 Node* weak_cell = 1492 Comment("LoadGlobalIC_TryPropertyCellCase");
1484 LoadFixedArrayElement(p->vector, p->slot, 0, SMI_PARAMETERS); 1493
1494 Node* weak_cell = LoadFixedArrayElement(vector, slot, 0, slot_mode);
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::LoadGlobalIC_TryHandlerCase(const LoadICParameters* p,
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("LoadGlobalIC_TryHandlerCase");
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->ReturnCallStub(descriptor, handler, p->context, receiver,
1518 p->vector); 1532 p->name, 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::LoadGlobalIC_MissCase(const LoadICParameters* p,
1537 ExitPoint* exit_point) {
1538 Comment("LoadGlobalIC_MissCase");
1539
1540 exit_point->ReturnCallRuntime(Runtime::kLoadGlobalIC_Miss, p->context,
1541 p->name, 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 LoadGlobalIC_TryPropertyCellCase(p->vector, p->slot, &direct_exit,
1550 &try_handler, &miss);
1551
1552 Bind(&try_handler);
1553 LoadGlobalIC_TryHandlerCase(p, typeof_mode, &direct_exit, &miss);
1554
1555 Bind(&miss);
1556 LoadGlobalIC_MissCase(p, &direct_exit);
1557 }
1558
1527 void AccessorAssembler::KeyedLoadIC(const LoadICParameters* p) { 1559 void AccessorAssembler::KeyedLoadIC(const LoadICParameters* p) {
1528 Variable var_handler(this, MachineRepresentation::kTagged); 1560 Variable var_handler(this, MachineRepresentation::kTagged);
1529 // TODO(ishell): defer blocks when it works. 1561 // TODO(ishell): defer blocks when it works.
1530 Label if_handler(this, &var_handler), try_polymorphic(this), 1562 Label if_handler(this, &var_handler), try_polymorphic(this),
1531 try_megamorphic(this /*, Label::kDeferred*/), 1563 try_megamorphic(this /*, Label::kDeferred*/),
1532 try_polymorphic_name(this /*, Label::kDeferred*/), 1564 try_polymorphic_name(this /*, Label::kDeferred*/),
1533 miss(this /*, Label::kDeferred*/); 1565 miss(this /*, Label::kDeferred*/);
1534 1566
1535 Node* receiver_map = LoadReceiverMap(p->receiver); 1567 Node* receiver_map = LoadReceiverMap(p->receiver);
1536 1568
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after
1822 void AccessorAssembler::GenerateLoadField() { 1854 void AccessorAssembler::GenerateLoadField() {
1823 typedef LoadFieldDescriptor Descriptor; 1855 typedef LoadFieldDescriptor Descriptor;
1824 1856
1825 Node* receiver = Parameter(Descriptor::kReceiver); 1857 Node* receiver = Parameter(Descriptor::kReceiver);
1826 Node* name = nullptr; 1858 Node* name = nullptr;
1827 Node* slot = nullptr; 1859 Node* slot = nullptr;
1828 Node* vector = nullptr; 1860 Node* vector = nullptr;
1829 Node* context = Parameter(Descriptor::kContext); 1861 Node* context = Parameter(Descriptor::kContext);
1830 LoadICParameters p(context, receiver, name, slot, vector); 1862 LoadICParameters p(context, receiver, name, slot, vector);
1831 1863
1864 ExitPoint direct_exit(this);
1865
1832 HandleLoadICSmiHandlerCase(&p, receiver, Parameter(Descriptor::kSmiHandler), 1866 HandleLoadICSmiHandlerCase(&p, receiver, Parameter(Descriptor::kSmiHandler),
1833 nullptr, kOnlyProperties); 1867 nullptr, &direct_exit, kOnlyProperties);
1834 } 1868 }
1835 1869
1836 void AccessorAssembler::GenerateLoadGlobalIC(TypeofMode typeof_mode) { 1870 void AccessorAssembler::GenerateLoadGlobalIC(TypeofMode typeof_mode) {
1837 typedef LoadGlobalWithVectorDescriptor Descriptor; 1871 typedef LoadGlobalWithVectorDescriptor Descriptor;
1838 1872
1839 Node* name = Parameter(Descriptor::kName); 1873 Node* name = Parameter(Descriptor::kName);
1840 Node* slot = Parameter(Descriptor::kSlot); 1874 Node* slot = Parameter(Descriptor::kSlot);
1841 Node* vector = Parameter(Descriptor::kVector); 1875 Node* vector = Parameter(Descriptor::kVector);
1842 Node* context = Parameter(Descriptor::kContext); 1876 Node* context = Parameter(Descriptor::kContext);
1843 1877
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
1948 Node* slot = Parameter(Descriptor::kSlot); 1982 Node* slot = Parameter(Descriptor::kSlot);
1949 Node* context = Parameter(Descriptor::kContext); 1983 Node* context = Parameter(Descriptor::kContext);
1950 Node* vector = LoadFeedbackVectorForStub(); 1984 Node* vector = LoadFeedbackVectorForStub();
1951 1985
1952 StoreICParameters p(context, receiver, name, value, slot, vector); 1986 StoreICParameters p(context, receiver, name, value, slot, vector);
1953 KeyedStoreIC(&p, language_mode); 1987 KeyedStoreIC(&p, language_mode);
1954 } 1988 }
1955 1989
1956 } // namespace internal 1990 } // namespace internal
1957 } // namespace v8 1991 } // namespace v8
OLDNEW
« no previous file with comments | « src/ic/accessor-assembler.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698