OLD | NEW |
---|---|
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/ic/accessor-assembler.h" | 5 #include "src/ic/accessor-assembler.h" |
6 #include "src/ic/accessor-assembler-impl.h" | 6 #include "src/ic/accessor-assembler-impl.h" |
7 | 7 |
8 #include "src/code-factory.h" | 8 #include "src/code-factory.h" |
9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
10 #include "src/ic/handler-configuration.h" | 10 #include "src/ic/handler-configuration.h" |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
159 // for the encoding format. | 159 // for the encoding format. |
160 Bind(&if_smi_handler); | 160 Bind(&if_smi_handler); |
161 { | 161 { |
162 HandleLoadICSmiHandlerCase(p, var_holder.value(), var_smi_handler.value(), | 162 HandleLoadICSmiHandlerCase(p, var_holder.value(), var_smi_handler.value(), |
163 miss, support_elements); | 163 miss, support_elements); |
164 } | 164 } |
165 | 165 |
166 Bind(&try_proto_handler); | 166 Bind(&try_proto_handler); |
167 { | 167 { |
168 GotoIf(IsCodeMap(LoadMap(handler)), &call_handler); | 168 GotoIf(IsCodeMap(LoadMap(handler)), &call_handler); |
169 HandleLoadICProtoHandler(p, handler, &var_holder, &var_smi_handler, | 169 HandleLoadICProtoHandlerCase(p, handler, &var_holder, &var_smi_handler, |
170 &if_smi_handler, miss); | 170 &if_smi_handler, miss, false); |
171 } | 171 } |
172 | 172 |
173 Bind(&call_handler); | 173 Bind(&call_handler); |
174 { | 174 { |
175 typedef LoadWithVectorDescriptor Descriptor; | 175 typedef LoadWithVectorDescriptor Descriptor; |
176 TailCallStub(Descriptor(isolate()), handler, p->context, | 176 TailCallStub(Descriptor(isolate()), handler, p->context, |
177 Arg(Descriptor::kReceiver, p->receiver), | 177 Arg(Descriptor::kReceiver, p->receiver), |
178 Arg(Descriptor::kName, p->name), | 178 Arg(Descriptor::kName, p->name), |
179 Arg(Descriptor::kSlot, p->slot), | 179 Arg(Descriptor::kSlot, p->slot), |
180 Arg(Descriptor::kVector, p->vector)); | 180 Arg(Descriptor::kVector, p->vector)); |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
297 GotoIf(IsSetWord<LoadHandler::IsAccessorInfoBits>(handler_word), | 297 GotoIf(IsSetWord<LoadHandler::IsAccessorInfoBits>(handler_word), |
298 &if_accessor_info); | 298 &if_accessor_info); |
299 Return(value); | 299 Return(value); |
300 | 300 |
301 Bind(&if_accessor_info); | 301 Bind(&if_accessor_info); |
302 Callable callable = CodeFactory::ApiGetter(isolate()); | 302 Callable callable = CodeFactory::ApiGetter(isolate()); |
303 TailCallStub(callable, p->context, p->receiver, holder, value); | 303 TailCallStub(callable, p->context, p->receiver, holder, value); |
304 } | 304 } |
305 } | 305 } |
306 | 306 |
307 void AccessorAssemblerImpl::HandleLoadICProtoHandler( | 307 void AccessorAssemblerImpl::HandleLoadICProtoHandlerCase( |
308 const LoadICParameters* p, Node* handler, Variable* var_holder, | 308 const LoadICParameters* p, Node* handler, Variable* var_holder, |
309 Variable* var_smi_handler, Label* if_smi_handler, Label* miss) { | 309 Variable* var_smi_handler, Label* if_smi_handler, Label* miss, |
310 bool throw_reference_error_if_nonexistent) { | |
310 DCHECK_EQ(MachineRepresentation::kTagged, var_holder->rep()); | 311 DCHECK_EQ(MachineRepresentation::kTagged, var_holder->rep()); |
311 DCHECK_EQ(MachineRepresentation::kTagged, var_smi_handler->rep()); | 312 DCHECK_EQ(MachineRepresentation::kTagged, var_smi_handler->rep()); |
312 | 313 |
313 // IC dispatchers rely on these assumptions to be held. | 314 // IC dispatchers rely on these assumptions to be held. |
314 STATIC_ASSERT(FixedArray::kLengthOffset == LoadHandler::kHolderCellOffset); | 315 STATIC_ASSERT(FixedArray::kLengthOffset == LoadHandler::kHolderCellOffset); |
315 DCHECK_EQ(FixedArray::OffsetOfElementAt(LoadHandler::kSmiHandlerIndex), | 316 DCHECK_EQ(FixedArray::OffsetOfElementAt(LoadHandler::kSmiHandlerIndex), |
316 LoadHandler::kSmiHandlerOffset); | 317 LoadHandler::kSmiHandlerOffset); |
317 DCHECK_EQ(FixedArray::OffsetOfElementAt(LoadHandler::kValidityCellIndex), | 318 DCHECK_EQ(FixedArray::OffsetOfElementAt(LoadHandler::kValidityCellIndex), |
318 LoadHandler::kValidityCellOffset); | 319 LoadHandler::kValidityCellOffset); |
319 | 320 |
(...skipping 28 matching lines...) Expand all Loading... | |
348 Node* maybe_holder_cell = | 349 Node* maybe_holder_cell = |
349 LoadObjectField(handler, LoadHandler::kHolderCellOffset); | 350 LoadObjectField(handler, LoadHandler::kHolderCellOffset); |
350 Label array_handler(this), tuple_handler(this); | 351 Label array_handler(this), tuple_handler(this); |
351 Branch(TaggedIsSmi(maybe_holder_cell), &array_handler, &tuple_handler); | 352 Branch(TaggedIsSmi(maybe_holder_cell), &array_handler, &tuple_handler); |
352 | 353 |
353 Bind(&tuple_handler); | 354 Bind(&tuple_handler); |
354 { | 355 { |
355 Label load_existent(this); | 356 Label load_existent(this); |
356 GotoIf(WordNotEqual(maybe_holder_cell, NullConstant()), &load_existent); | 357 GotoIf(WordNotEqual(maybe_holder_cell, NullConstant()), &load_existent); |
357 // This is a handler for a load of a non-existent value. | 358 // This is a handler for a load of a non-existent value. |
358 Return(UndefinedConstant()); | 359 if (throw_reference_error_if_nonexistent) { |
360 TailCallRuntime(Runtime::kThrowReferenceError, p->context, p->name); | |
361 } else { | |
362 Return(UndefinedConstant()); | |
363 } | |
359 | 364 |
360 Bind(&load_existent); | 365 Bind(&load_existent); |
361 Node* holder = LoadWeakCellValue(maybe_holder_cell); | 366 Node* holder = LoadWeakCellValue(maybe_holder_cell); |
362 // The |holder| is guaranteed to be alive at this point since we passed | 367 // The |holder| is guaranteed to be alive at this point since we passed |
363 // both the receiver map check and the validity cell check. | 368 // both the receiver map check and the validity cell check. |
364 CSA_ASSERT(this, WordNotEqual(holder, IntPtrConstant(0))); | 369 CSA_ASSERT(this, WordNotEqual(holder, IntPtrConstant(0))); |
365 | 370 |
366 var_holder->Bind(holder); | 371 var_holder->Bind(holder); |
367 var_smi_handler->Bind(smi_handler); | 372 var_smi_handler->Bind(smi_handler); |
368 Goto(if_smi_handler); | 373 Goto(if_smi_handler); |
369 } | 374 } |
370 | 375 |
371 Bind(&array_handler); | 376 Bind(&array_handler); |
372 { | 377 { |
373 typedef LoadICProtoArrayDescriptor Descriptor; | 378 typedef LoadICProtoArrayDescriptor Descriptor; |
374 LoadICProtoArrayStub stub(isolate()); | 379 LoadICProtoArrayStub stub(isolate(), throw_reference_error_if_nonexistent); |
375 Node* target = HeapConstant(stub.GetCode()); | 380 Node* target = HeapConstant(stub.GetCode()); |
376 TailCallStub(Descriptor(isolate()), target, p->context, | 381 TailCallStub(Descriptor(isolate()), target, p->context, |
377 Arg(Descriptor::kReceiver, p->receiver), | 382 Arg(Descriptor::kReceiver, p->receiver), |
378 Arg(Descriptor::kName, p->name), | 383 Arg(Descriptor::kName, p->name), |
379 Arg(Descriptor::kSlot, p->slot), | 384 Arg(Descriptor::kSlot, p->slot), |
380 Arg(Descriptor::kVector, p->vector), | 385 Arg(Descriptor::kVector, p->vector), |
381 Arg(Descriptor::kHandler, handler)); | 386 Arg(Descriptor::kHandler, handler)); |
382 } | 387 } |
383 } | 388 } |
384 | 389 |
385 Node* AccessorAssemblerImpl::EmitLoadICProtoArrayCheck( | 390 Node* AccessorAssemblerImpl::EmitLoadICProtoArrayCheck( |
386 const LoadICParameters* p, Node* handler, Node* handler_length, | 391 const LoadICParameters* p, Node* handler, Node* handler_length, |
387 Node* handler_flags, Label* miss) { | 392 Node* handler_flags, Label* miss, |
393 bool throw_reference_error_if_nonexistent) { | |
388 Variable start_index(this, MachineType::PointerRepresentation()); | 394 Variable start_index(this, MachineType::PointerRepresentation()); |
389 start_index.Bind(IntPtrConstant(LoadHandler::kFirstPrototypeIndex)); | 395 start_index.Bind(IntPtrConstant(LoadHandler::kFirstPrototypeIndex)); |
390 | 396 |
391 Label can_access(this); | 397 Label can_access(this); |
392 GotoUnless(IsSetWord<LoadHandler::DoAccessCheckOnReceiverBits>(handler_flags), | 398 GotoUnless(IsSetWord<LoadHandler::DoAccessCheckOnReceiverBits>(handler_flags), |
393 &can_access); | 399 &can_access); |
394 { | 400 { |
395 // Skip this entry of a handler. | 401 // Skip this entry of a handler. |
396 start_index.Bind(IntPtrConstant(LoadHandler::kFirstPrototypeIndex + 1)); | 402 start_index.Bind(IntPtrConstant(LoadHandler::kFirstPrototypeIndex + 1)); |
397 | 403 |
(...skipping 25 matching lines...) Expand all Loading... | |
423 CheckPrototype(prototype_cell, p->name, miss); | 429 CheckPrototype(prototype_cell, p->name, miss); |
424 }, | 430 }, |
425 1, IndexAdvanceMode::kPost); | 431 1, IndexAdvanceMode::kPost); |
426 | 432 |
427 Node* maybe_holder_cell = LoadFixedArrayElement( | 433 Node* maybe_holder_cell = LoadFixedArrayElement( |
428 handler, IntPtrConstant(LoadHandler::kHolderCellIndex), 0, | 434 handler, IntPtrConstant(LoadHandler::kHolderCellIndex), 0, |
429 INTPTR_PARAMETERS); | 435 INTPTR_PARAMETERS); |
430 Label load_existent(this); | 436 Label load_existent(this); |
431 GotoIf(WordNotEqual(maybe_holder_cell, NullConstant()), &load_existent); | 437 GotoIf(WordNotEqual(maybe_holder_cell, NullConstant()), &load_existent); |
432 // This is a handler for a load of a non-existent value. | 438 // This is a handler for a load of a non-existent value. |
433 Return(UndefinedConstant()); | 439 if (throw_reference_error_if_nonexistent) { |
440 TailCallRuntime(Runtime::kThrowReferenceError, p->context, p->name); | |
441 } else { | |
442 Return(UndefinedConstant()); | |
443 } | |
434 | 444 |
435 Bind(&load_existent); | 445 Bind(&load_existent); |
436 Node* holder = LoadWeakCellValue(maybe_holder_cell); | 446 Node* holder = LoadWeakCellValue(maybe_holder_cell); |
437 // The |holder| is guaranteed to be alive at this point since we passed | 447 // The |holder| is guaranteed to be alive at this point since we passed |
438 // the receiver map check, the validity cell check and the prototype chain | 448 // the receiver map check, the validity cell check and the prototype chain |
439 // check. | 449 // check. |
440 CSA_ASSERT(this, WordNotEqual(holder, IntPtrConstant(0))); | 450 CSA_ASSERT(this, WordNotEqual(holder, IntPtrConstant(0))); |
441 return holder; | 451 return holder; |
442 } | 452 } |
443 | 453 |
(...skipping 669 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1113 TryProbeStubCache(isolate()->load_stub_cache(), p->receiver, p->name, | 1123 TryProbeStubCache(isolate()->load_stub_cache(), p->receiver, p->name, |
1114 &if_handler, &var_handler, &miss); | 1124 &if_handler, &var_handler, &miss); |
1115 } | 1125 } |
1116 Bind(&miss); | 1126 Bind(&miss); |
1117 { | 1127 { |
1118 TailCallRuntime(Runtime::kLoadIC_Miss, p->context, p->receiver, p->name, | 1128 TailCallRuntime(Runtime::kLoadIC_Miss, p->context, p->receiver, p->name, |
1119 p->slot, p->vector); | 1129 p->slot, p->vector); |
1120 } | 1130 } |
1121 } | 1131 } |
1122 | 1132 |
1123 void AccessorAssemblerImpl::LoadICProtoArray(const LoadICParameters* p, | 1133 void AccessorAssemblerImpl::LoadICProtoArray( |
1124 Node* handler) { | 1134 const LoadICParameters* p, Node* handler, |
1135 bool throw_reference_error_if_nonexistent) { | |
1125 Label miss(this); | 1136 Label miss(this); |
1126 CSA_ASSERT(this, Word32BinaryNot(TaggedIsSmi(handler))); | 1137 CSA_ASSERT(this, Word32BinaryNot(TaggedIsSmi(handler))); |
1127 CSA_ASSERT(this, IsFixedArrayMap(LoadMap(handler))); | 1138 CSA_ASSERT(this, IsFixedArrayMap(LoadMap(handler))); |
1128 | 1139 |
1129 Node* smi_handler = LoadObjectField(handler, LoadHandler::kSmiHandlerOffset); | 1140 Node* smi_handler = LoadObjectField(handler, LoadHandler::kSmiHandlerOffset); |
1130 Node* handler_flags = SmiUntag(smi_handler); | 1141 Node* handler_flags = SmiUntag(smi_handler); |
1131 | 1142 |
1132 Node* handler_length = LoadAndUntagFixedArrayBaseLength(handler); | 1143 Node* handler_length = LoadAndUntagFixedArrayBaseLength(handler); |
1133 | 1144 |
1134 Node* holder = EmitLoadICProtoArrayCheck(p, handler, handler_length, | 1145 Node* holder = |
1135 handler_flags, &miss); | 1146 EmitLoadICProtoArrayCheck(p, handler, handler_length, handler_flags, |
1147 &miss, throw_reference_error_if_nonexistent); | |
1136 | 1148 |
1137 HandleLoadICSmiHandlerCase(p, holder, smi_handler, &miss, kOnlyProperties); | 1149 HandleLoadICSmiHandlerCase(p, holder, smi_handler, &miss, kOnlyProperties); |
1138 | 1150 |
1139 Bind(&miss); | 1151 Bind(&miss); |
1140 { | 1152 { |
1141 TailCallRuntime(Runtime::kLoadIC_Miss, p->context, p->receiver, p->name, | 1153 TailCallRuntime(Runtime::kLoadIC_Miss, p->context, p->receiver, p->name, |
1142 p->slot, p->vector); | 1154 p->slot, p->vector); |
1143 } | 1155 } |
1144 } | 1156 } |
1145 | 1157 |
1146 void AccessorAssemblerImpl::LoadGlobalIC(const LoadICParameters* p) { | 1158 void AccessorAssemblerImpl::LoadGlobalIC(const LoadICParameters* p, |
1147 Label try_handler(this), miss(this); | 1159 TypeofMode typeof_mode) { |
1160 Label try_handler(this), call_handler(this), miss(this); | |
1148 Node* weak_cell = | 1161 Node* weak_cell = |
1149 LoadFixedArrayElement(p->vector, p->slot, 0, SMI_PARAMETERS); | 1162 LoadFixedArrayElement(p->vector, p->slot, 0, SMI_PARAMETERS); |
1150 CSA_ASSERT(this, HasInstanceType(weak_cell, WEAK_CELL_TYPE)); | 1163 CSA_ASSERT(this, HasInstanceType(weak_cell, WEAK_CELL_TYPE)); |
1151 | 1164 |
1152 // Load value or try handler case if the {weak_cell} is cleared. | 1165 // Load value or try handler case if the {weak_cell} is cleared. |
1153 Node* property_cell = LoadWeakCellValue(weak_cell, &try_handler); | 1166 Node* property_cell = LoadWeakCellValue(weak_cell, &try_handler); |
1154 CSA_ASSERT(this, HasInstanceType(property_cell, PROPERTY_CELL_TYPE)); | 1167 CSA_ASSERT(this, HasInstanceType(property_cell, PROPERTY_CELL_TYPE)); |
1155 | 1168 |
1156 Node* value = LoadObjectField(property_cell, PropertyCell::kValueOffset); | 1169 Node* value = LoadObjectField(property_cell, PropertyCell::kValueOffset); |
1157 GotoIf(WordEqual(value, TheHoleConstant()), &miss); | 1170 GotoIf(WordEqual(value, TheHoleConstant()), &miss); |
1158 Return(value); | 1171 Return(value); |
1159 | 1172 |
1173 Node* handler; | |
1160 Bind(&try_handler); | 1174 Bind(&try_handler); |
1161 { | 1175 { |
1162 Node* handler = | 1176 handler = |
1163 LoadFixedArrayElement(p->vector, p->slot, kPointerSize, SMI_PARAMETERS); | 1177 LoadFixedArrayElement(p->vector, p->slot, kPointerSize, SMI_PARAMETERS); |
1178 CSA_ASSERT(this, Word32BinaryNot(TaggedIsSmi(handler))); | |
1164 GotoIf(WordEqual(handler, LoadRoot(Heap::kuninitialized_symbolRootIndex)), | 1179 GotoIf(WordEqual(handler, LoadRoot(Heap::kuninitialized_symbolRootIndex)), |
1165 &miss); | 1180 &miss); |
1181 GotoIf(IsCodeMap(LoadMap(handler)), &call_handler); | |
1166 | 1182 |
1167 // In this case {handler} must be a Code object. | 1183 bool throw_reference_error_if_nonexistent = |
1168 CSA_ASSERT(this, HasInstanceType(handler, CODE_TYPE)); | 1184 typeof_mode == NOT_INSIDE_TYPEOF; |
1185 HandleLoadGlobalICHandlerCase(p, handler, &miss, | |
1186 throw_reference_error_if_nonexistent); | |
1187 } | |
1188 | |
1189 Bind(&call_handler); | |
1190 { | |
1169 LoadWithVectorDescriptor descriptor(isolate()); | 1191 LoadWithVectorDescriptor descriptor(isolate()); |
1170 Node* native_context = LoadNativeContext(p->context); | 1192 Node* native_context = LoadNativeContext(p->context); |
1171 Node* receiver = | 1193 Node* receiver = |
1172 LoadContextElement(native_context, Context::EXTENSION_INDEX); | 1194 LoadContextElement(native_context, Context::EXTENSION_INDEX); |
1173 TailCallStub(descriptor, handler, p->context, receiver, p->name, p->slot, | 1195 TailCallStub(descriptor, handler, p->context, receiver, p->name, p->slot, |
1174 p->vector); | 1196 p->vector); |
1175 } | 1197 } |
1176 Bind(&miss); | 1198 Bind(&miss); |
1177 { | 1199 { |
1178 TailCallRuntime(Runtime::kLoadGlobalIC_Miss, p->context, p->slot, | 1200 TailCallRuntime(Runtime::kLoadGlobalIC_Miss, p->context, p->slot, |
1179 p->vector); | 1201 p->vector); |
1180 } | 1202 } |
1181 } | 1203 } |
1182 | 1204 |
1205 void AccessorAssemblerImpl::HandleLoadGlobalICHandlerCase( | |
Jakob Kummerow
2016/11/17 10:44:21
nit: please move this up to where the other Handle
Igor Sheludko
2016/11/17 11:32:08
Done.
| |
1206 const LoadICParameters* pp, Node* handler, Label* miss, | |
1207 bool throw_reference_error_if_nonexistent) { | |
1208 LoadICParameters p = *pp; | |
1209 DCHECK_NULL(p.receiver); | |
1210 Node* native_context = LoadNativeContext(p.context); | |
1211 p.receiver = LoadContextElement(native_context, Context::EXTENSION_INDEX); | |
1212 | |
1213 Variable var_holder(this, MachineRepresentation::kTagged); | |
1214 Variable var_smi_handler(this, MachineRepresentation::kTagged); | |
1215 Label if_smi_handler(this); | |
1216 HandleLoadICProtoHandlerCase(&p, handler, &var_holder, &var_smi_handler, | |
1217 &if_smi_handler, miss, | |
1218 throw_reference_error_if_nonexistent); | |
1219 Bind(&if_smi_handler); | |
1220 HandleLoadICSmiHandlerCase(&p, var_holder.value(), var_smi_handler.value(), | |
1221 miss, kOnlyProperties); | |
1222 } | |
1223 | |
1183 void AccessorAssemblerImpl::KeyedLoadIC(const LoadICParameters* p) { | 1224 void AccessorAssemblerImpl::KeyedLoadIC(const LoadICParameters* p) { |
1184 Variable var_handler(this, MachineRepresentation::kTagged); | 1225 Variable var_handler(this, MachineRepresentation::kTagged); |
1185 // TODO(ishell): defer blocks when it works. | 1226 // TODO(ishell): defer blocks when it works. |
1186 Label if_handler(this, &var_handler), try_polymorphic(this), | 1227 Label if_handler(this, &var_handler), try_polymorphic(this), |
1187 try_megamorphic(this /*, Label::kDeferred*/), | 1228 try_megamorphic(this /*, Label::kDeferred*/), |
1188 try_polymorphic_name(this /*, Label::kDeferred*/), | 1229 try_polymorphic_name(this /*, Label::kDeferred*/), |
1189 miss(this /*, Label::kDeferred*/); | 1230 miss(this /*, Label::kDeferred*/); |
1190 | 1231 |
1191 Node* receiver_map = LoadReceiverMap(p->receiver); | 1232 Node* receiver_map = LoadReceiverMap(p->receiver); |
1192 | 1233 |
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1544 Node* receiver = Parameter(Descriptor::kReceiver); | 1585 Node* receiver = Parameter(Descriptor::kReceiver); |
1545 Node* name = Parameter(Descriptor::kName); | 1586 Node* name = Parameter(Descriptor::kName); |
1546 Node* slot = Parameter(Descriptor::kSlot); | 1587 Node* slot = Parameter(Descriptor::kSlot); |
1547 Node* context = Parameter(Descriptor::kContext); | 1588 Node* context = Parameter(Descriptor::kContext); |
1548 Node* vector = LoadTypeFeedbackVectorForStub(); | 1589 Node* vector = LoadTypeFeedbackVectorForStub(); |
1549 | 1590 |
1550 LoadICParameters p(context, receiver, name, slot, vector); | 1591 LoadICParameters p(context, receiver, name, slot, vector); |
1551 LoadIC(&p); | 1592 LoadIC(&p); |
1552 } | 1593 } |
1553 | 1594 |
1554 void AccessorAssemblerImpl::GenerateLoadICProtoArray() { | 1595 void AccessorAssemblerImpl::GenerateLoadICProtoArray( |
1596 bool throw_reference_error_if_nonexistent) { | |
1555 typedef LoadICProtoArrayStub::Descriptor Descriptor; | 1597 typedef LoadICProtoArrayStub::Descriptor Descriptor; |
1556 | 1598 |
1557 Node* receiver = Parameter(Descriptor::kReceiver); | 1599 Node* receiver = Parameter(Descriptor::kReceiver); |
1558 Node* name = Parameter(Descriptor::kName); | 1600 Node* name = Parameter(Descriptor::kName); |
1559 Node* slot = Parameter(Descriptor::kSlot); | 1601 Node* slot = Parameter(Descriptor::kSlot); |
1560 Node* vector = Parameter(Descriptor::kVector); | 1602 Node* vector = Parameter(Descriptor::kVector); |
1561 Node* handler = Parameter(Descriptor::kHandler); | 1603 Node* handler = Parameter(Descriptor::kHandler); |
1562 Node* context = Parameter(Descriptor::kContext); | 1604 Node* context = Parameter(Descriptor::kContext); |
1563 | 1605 |
1564 LoadICParameters p(context, receiver, name, slot, vector); | 1606 LoadICParameters p(context, receiver, name, slot, vector); |
1565 LoadICProtoArray(&p, handler); | 1607 LoadICProtoArray(&p, handler, throw_reference_error_if_nonexistent); |
1566 } | 1608 } |
1567 | 1609 |
1568 void AccessorAssemblerImpl::GenerateLoadGlobalIC() { | 1610 void AccessorAssemblerImpl::GenerateLoadGlobalIC(TypeofMode typeof_mode) { |
1569 typedef LoadGlobalICStub::Descriptor Descriptor; | 1611 typedef LoadGlobalICStub::Descriptor Descriptor; |
1570 | 1612 |
1571 Node* name = Parameter(Descriptor::kName); | 1613 Node* name = Parameter(Descriptor::kName); |
1572 Node* slot = Parameter(Descriptor::kSlot); | 1614 Node* slot = Parameter(Descriptor::kSlot); |
1573 Node* vector = Parameter(Descriptor::kVector); | 1615 Node* vector = Parameter(Descriptor::kVector); |
1574 Node* context = Parameter(Descriptor::kContext); | 1616 Node* context = Parameter(Descriptor::kContext); |
1575 | 1617 |
1576 LoadICParameters p(context, nullptr, name, slot, vector); | 1618 LoadICParameters p(context, nullptr, name, slot, vector); |
1577 LoadGlobalIC(&p); | 1619 LoadGlobalIC(&p, typeof_mode); |
1578 } | 1620 } |
1579 | 1621 |
1580 void AccessorAssemblerImpl::GenerateLoadGlobalICTrampoline() { | 1622 void AccessorAssemblerImpl::GenerateLoadGlobalICTrampoline( |
1623 TypeofMode typeof_mode) { | |
1581 typedef LoadGlobalICTrampolineStub::Descriptor Descriptor; | 1624 typedef LoadGlobalICTrampolineStub::Descriptor Descriptor; |
1582 | 1625 |
1583 Node* name = Parameter(Descriptor::kName); | 1626 Node* name = Parameter(Descriptor::kName); |
1584 Node* slot = Parameter(Descriptor::kSlot); | 1627 Node* slot = Parameter(Descriptor::kSlot); |
1585 Node* context = Parameter(Descriptor::kContext); | 1628 Node* context = Parameter(Descriptor::kContext); |
1586 Node* vector = LoadTypeFeedbackVectorForStub(); | 1629 Node* vector = LoadTypeFeedbackVectorForStub(); |
1587 | 1630 |
1588 LoadICParameters p(context, nullptr, name, slot, vector); | 1631 LoadICParameters p(context, nullptr, name, slot, vector); |
1589 LoadGlobalIC(&p); | 1632 LoadGlobalIC(&p, typeof_mode); |
1590 } | 1633 } |
1591 | 1634 |
1592 void AccessorAssemblerImpl::GenerateKeyedLoadICTF() { | 1635 void AccessorAssemblerImpl::GenerateKeyedLoadICTF() { |
1593 typedef KeyedLoadICTFStub::Descriptor Descriptor; | 1636 typedef KeyedLoadICTFStub::Descriptor Descriptor; |
1594 | 1637 |
1595 Node* receiver = Parameter(Descriptor::kReceiver); | 1638 Node* receiver = Parameter(Descriptor::kReceiver); |
1596 Node* name = Parameter(Descriptor::kName); | 1639 Node* name = Parameter(Descriptor::kName); |
1597 Node* slot = Parameter(Descriptor::kSlot); | 1640 Node* slot = Parameter(Descriptor::kSlot); |
1598 Node* vector = Parameter(Descriptor::kVector); | 1641 Node* vector = Parameter(Descriptor::kVector); |
1599 Node* context = Parameter(Descriptor::kContext); | 1642 Node* context = Parameter(Descriptor::kContext); |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1689 | 1732 |
1690 #define DISPATCH_TO_IMPL(Name) \ | 1733 #define DISPATCH_TO_IMPL(Name) \ |
1691 void AccessorAssembler::Generate##Name(CodeAssemblerState* state) { \ | 1734 void AccessorAssembler::Generate##Name(CodeAssemblerState* state) { \ |
1692 AccessorAssemblerImpl assembler(state); \ | 1735 AccessorAssemblerImpl assembler(state); \ |
1693 assembler.Generate##Name(); \ | 1736 assembler.Generate##Name(); \ |
1694 } | 1737 } |
1695 | 1738 |
1696 ACCESSOR_ASSEMBLER_PUBLIC_INTERFACE(DISPATCH_TO_IMPL) | 1739 ACCESSOR_ASSEMBLER_PUBLIC_INTERFACE(DISPATCH_TO_IMPL) |
1697 #undef DISPATCH_TO_IMPL | 1740 #undef DISPATCH_TO_IMPL |
1698 | 1741 |
1742 void AccessorAssembler::GenerateLoadICProtoArray( | |
1743 CodeAssemblerState* state, bool throw_reference_error_if_nonexistent) { | |
1744 AccessorAssemblerImpl assembler(state); | |
1745 assembler.GenerateLoadICProtoArray(throw_reference_error_if_nonexistent); | |
1746 } | |
1747 | |
1748 void AccessorAssembler::GenerateLoadGlobalIC(CodeAssemblerState* state, | |
1749 TypeofMode typeof_mode) { | |
1750 AccessorAssemblerImpl assembler(state); | |
1751 assembler.GenerateLoadGlobalIC(typeof_mode); | |
1752 } | |
1753 | |
1754 void AccessorAssembler::GenerateLoadGlobalICTrampoline( | |
1755 CodeAssemblerState* state, TypeofMode typeof_mode) { | |
1756 AccessorAssemblerImpl assembler(state); | |
1757 assembler.GenerateLoadGlobalICTrampoline(typeof_mode); | |
1758 } | |
1759 | |
1699 void AccessorAssembler::GenerateKeyedStoreICTF(CodeAssemblerState* state, | 1760 void AccessorAssembler::GenerateKeyedStoreICTF(CodeAssemblerState* state, |
1700 LanguageMode language_mode) { | 1761 LanguageMode language_mode) { |
1701 AccessorAssemblerImpl assembler(state); | 1762 AccessorAssemblerImpl assembler(state); |
1702 assembler.GenerateKeyedStoreICTF(language_mode); | 1763 assembler.GenerateKeyedStoreICTF(language_mode); |
1703 } | 1764 } |
1704 | 1765 |
1705 void AccessorAssembler::GenerateKeyedStoreICTrampolineTF( | 1766 void AccessorAssembler::GenerateKeyedStoreICTrampolineTF( |
1706 CodeAssemblerState* state, LanguageMode language_mode) { | 1767 CodeAssemblerState* state, LanguageMode language_mode) { |
1707 AccessorAssemblerImpl assembler(state); | 1768 AccessorAssemblerImpl assembler(state); |
1708 assembler.GenerateKeyedStoreICTrampolineTF(language_mode); | 1769 assembler.GenerateKeyedStoreICTrampolineTF(language_mode); |
1709 } | 1770 } |
1710 | 1771 |
1711 #undef ACCESSOR_ASSEMBLER_PUBLIC_INTERFACE | 1772 #undef ACCESSOR_ASSEMBLER_PUBLIC_INTERFACE |
1712 | 1773 |
1713 } // namespace internal | 1774 } // namespace internal |
1714 } // namespace v8 | 1775 } // namespace v8 |
OLD | NEW |