OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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/compiler/js-native-context-specialization.h" | 5 #include "src/compiler/js-native-context-specialization.h" |
6 | 6 |
7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
8 #include "src/code-factory.h" | 8 #include "src/code-factory.h" |
9 #include "src/compilation-dependencies.h" | 9 #include "src/compilation-dependencies.h" |
10 #include "src/compiler/access-builder.h" | 10 #include "src/compiler/access-builder.h" |
(...skipping 1417 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1428 target, frame_state); | 1428 target, frame_state); |
1429 | 1429 |
1430 // Introduce the call to the getter function. | 1430 // Introduce the call to the getter function. |
1431 Node* value; | 1431 Node* value; |
1432 if (access_info.constant()->IsJSFunction()) { | 1432 if (access_info.constant()->IsJSFunction()) { |
1433 value = *effect = *control = graph()->NewNode( | 1433 value = *effect = *control = graph()->NewNode( |
1434 jsgraph()->javascript()->Call(2, CallFrequency(), VectorSlotPair(), | 1434 jsgraph()->javascript()->Call(2, CallFrequency(), VectorSlotPair(), |
1435 ConvertReceiverMode::kNotNullOrUndefined), | 1435 ConvertReceiverMode::kNotNullOrUndefined), |
1436 target, receiver, context, frame_state0, *effect, *control); | 1436 target, receiver, context, frame_state0, *effect, *control); |
1437 } else { | 1437 } else { |
| 1438 Node* holder = jsgraph()->Constant(access_info.holder().ToHandleChecked()); |
1438 DCHECK(access_info.constant()->IsFunctionTemplateInfo()); | 1439 DCHECK(access_info.constant()->IsFunctionTemplateInfo()); |
1439 Handle<FunctionTemplateInfo> function_template_info( | 1440 Handle<FunctionTemplateInfo> function_template_info( |
1440 Handle<FunctionTemplateInfo>::cast(access_info.constant())); | 1441 Handle<FunctionTemplateInfo>::cast(access_info.constant())); |
1441 DCHECK(!function_template_info->call_code()->IsUndefined(isolate())); | 1442 DCHECK(!function_template_info->call_code()->IsUndefined(isolate())); |
1442 value = InlineApiCall(receiver, context, target, frame_state0, nullptr, | 1443 value = |
1443 effect, control, shared_info, function_template_info); | 1444 InlineApiCall(receiver, holder, context, target, frame_state0, nullptr, |
| 1445 effect, control, shared_info, function_template_info); |
1444 } | 1446 } |
1445 // Remember to rewire the IfException edge if this is inside a try-block. | 1447 // Remember to rewire the IfException edge if this is inside a try-block. |
1446 if (if_exceptions != nullptr) { | 1448 if (if_exceptions != nullptr) { |
1447 // Create the appropriate IfException/IfSuccess projections. | 1449 // Create the appropriate IfException/IfSuccess projections. |
1448 Node* const if_exception = | 1450 Node* const if_exception = |
1449 graph()->NewNode(common()->IfException(), *control, *effect); | 1451 graph()->NewNode(common()->IfException(), *control, *effect); |
1450 Node* const if_success = graph()->NewNode(common()->IfSuccess(), *control); | 1452 Node* const if_success = graph()->NewNode(common()->IfSuccess(), *control); |
1451 if_exceptions->push_back(if_exception); | 1453 if_exceptions->push_back(if_exception); |
1452 *control = if_success; | 1454 *control = if_success; |
1453 } | 1455 } |
(...skipping 21 matching lines...) Expand all Loading... |
1475 jsgraph()->EmptyStateValues(), jsgraph()->EmptyStateValues(), context, | 1477 jsgraph()->EmptyStateValues(), jsgraph()->EmptyStateValues(), context, |
1476 target, frame_state); | 1478 target, frame_state); |
1477 | 1479 |
1478 // Introduce the call to the setter function. | 1480 // Introduce the call to the setter function. |
1479 if (access_info.constant()->IsJSFunction()) { | 1481 if (access_info.constant()->IsJSFunction()) { |
1480 *effect = *control = graph()->NewNode( | 1482 *effect = *control = graph()->NewNode( |
1481 jsgraph()->javascript()->Call(3, CallFrequency(), VectorSlotPair(), | 1483 jsgraph()->javascript()->Call(3, CallFrequency(), VectorSlotPair(), |
1482 ConvertReceiverMode::kNotNullOrUndefined), | 1484 ConvertReceiverMode::kNotNullOrUndefined), |
1483 target, receiver, value, context, frame_state0, *effect, *control); | 1485 target, receiver, value, context, frame_state0, *effect, *control); |
1484 } else { | 1486 } else { |
| 1487 Node* holder = jsgraph()->Constant(access_info.holder().ToHandleChecked()); |
1485 DCHECK(access_info.constant()->IsFunctionTemplateInfo()); | 1488 DCHECK(access_info.constant()->IsFunctionTemplateInfo()); |
1486 Handle<FunctionTemplateInfo> function_template_info( | 1489 Handle<FunctionTemplateInfo> function_template_info( |
1487 Handle<FunctionTemplateInfo>::cast(access_info.constant())); | 1490 Handle<FunctionTemplateInfo>::cast(access_info.constant())); |
1488 DCHECK(!function_template_info->call_code()->IsUndefined(isolate())); | 1491 DCHECK(!function_template_info->call_code()->IsUndefined(isolate())); |
1489 value = InlineApiCall(receiver, context, target, frame_state0, value, | 1492 value = |
1490 effect, control, shared_info, function_template_info); | 1493 InlineApiCall(receiver, holder, context, target, frame_state0, value, |
| 1494 effect, control, shared_info, function_template_info); |
1491 } | 1495 } |
1492 // Remember to rewire the IfException edge if this is inside a try-block. | 1496 // Remember to rewire the IfException edge if this is inside a try-block. |
1493 if (if_exceptions != nullptr) { | 1497 if (if_exceptions != nullptr) { |
1494 // Create the appropriate IfException/IfSuccess projections. | 1498 // Create the appropriate IfException/IfSuccess projections. |
1495 Node* const if_exception = | 1499 Node* const if_exception = |
1496 graph()->NewNode(common()->IfException(), *control, *effect); | 1500 graph()->NewNode(common()->IfException(), *control, *effect); |
1497 Node* const if_success = graph()->NewNode(common()->IfSuccess(), *control); | 1501 Node* const if_success = graph()->NewNode(common()->IfSuccess(), *control); |
1498 if_exceptions->push_back(if_exception); | 1502 if_exceptions->push_back(if_exception); |
1499 *control = if_success; | 1503 *control = if_success; |
1500 } | 1504 } |
1501 return value; | 1505 return value; |
1502 } | 1506 } |
1503 | 1507 |
1504 Node* JSNativeContextSpecialization::InlineApiCall( | 1508 Node* JSNativeContextSpecialization::InlineApiCall( |
1505 Node* receiver, Node* context, Node* target, Node* frame_state, Node* value, | 1509 Node* receiver, Node* holder, Node* context, Node* target, |
1506 Node** effect, Node** control, Handle<SharedFunctionInfo> shared_info, | 1510 Node* frame_state, Node* value, Node** effect, Node** control, |
| 1511 Handle<SharedFunctionInfo> shared_info, |
1507 Handle<FunctionTemplateInfo> function_template_info) { | 1512 Handle<FunctionTemplateInfo> function_template_info) { |
1508 Handle<CallHandlerInfo> call_handler_info = handle( | 1513 Handle<CallHandlerInfo> call_handler_info = handle( |
1509 CallHandlerInfo::cast(function_template_info->call_code()), isolate()); | 1514 CallHandlerInfo::cast(function_template_info->call_code()), isolate()); |
1510 Handle<Object> call_data_object(call_handler_info->data(), isolate()); | 1515 Handle<Object> call_data_object(call_handler_info->data(), isolate()); |
1511 | 1516 |
1512 // Only setters have a value. | 1517 // Only setters have a value. |
1513 int const argc = value == nullptr ? 0 : 1; | 1518 int const argc = value == nullptr ? 0 : 1; |
1514 // The stub always expects the receiver as the first param on the stack. | 1519 // The stub always expects the receiver as the first param on the stack. |
1515 CallApiCallbackStub stub( | 1520 CallApiCallbackStub stub( |
1516 isolate(), argc, | 1521 isolate(), argc, |
1517 true /* FunctionTemplateInfo doesn't have an associated context. */); | 1522 true /* FunctionTemplateInfo doesn't have an associated context. */); |
1518 CallInterfaceDescriptor call_interface_descriptor = | 1523 CallInterfaceDescriptor call_interface_descriptor = |
1519 stub.GetCallInterfaceDescriptor(); | 1524 stub.GetCallInterfaceDescriptor(); |
1520 CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor( | 1525 CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor( |
1521 isolate(), graph()->zone(), call_interface_descriptor, | 1526 isolate(), graph()->zone(), call_interface_descriptor, |
1522 call_interface_descriptor.GetStackParameterCount() + argc + | 1527 call_interface_descriptor.GetStackParameterCount() + argc + |
1523 1 /* implicit receiver */, | 1528 1 /* implicit receiver */ + 1 /* accessor holder */, |
1524 CallDescriptor::kNeedsFrameState, Operator::kNoProperties, | 1529 CallDescriptor::kNeedsFrameState, Operator::kNoProperties, |
1525 MachineType::AnyTagged(), 1); | 1530 MachineType::AnyTagged(), 1); |
1526 | 1531 |
1527 Node* data = jsgraph()->Constant(call_data_object); | 1532 Node* data = jsgraph()->Constant(call_data_object); |
1528 ApiFunction function(v8::ToCData<Address>(call_handler_info->callback())); | 1533 ApiFunction function(v8::ToCData<Address>(call_handler_info->callback())); |
1529 Node* function_reference = | 1534 Node* function_reference = |
1530 graph()->NewNode(common()->ExternalConstant(ExternalReference( | 1535 graph()->NewNode(common()->ExternalConstant(ExternalReference( |
1531 &function, ExternalReference::DIRECT_API_CALL, isolate()))); | 1536 &function, ExternalReference::DIRECT_API_CALL, isolate()))); |
1532 Node* code = jsgraph()->HeapConstant(stub.GetCode()); | 1537 Node* code = jsgraph()->HeapConstant(stub.GetCode()); |
1533 | 1538 |
1534 // Add CallApiCallbackStub's register argument as well. | 1539 // Add CallApiCallbackStub's register argument as well. |
1535 Node* inputs[11] = { | 1540 Node* inputs[12] = { |
1536 code, target, data, receiver /* holder */, function_reference, receiver}; | 1541 code, target, data, receiver /* holder */, function_reference, |
1537 int index = 6 + argc; | 1542 holder, receiver}; |
| 1543 int index = 7 + argc; |
1538 inputs[index++] = context; | 1544 inputs[index++] = context; |
1539 inputs[index++] = frame_state; | 1545 inputs[index++] = frame_state; |
1540 inputs[index++] = *effect; | 1546 inputs[index++] = *effect; |
1541 inputs[index++] = *control; | 1547 inputs[index++] = *control; |
1542 // This needs to stay here because of the edge case described in | 1548 // This needs to stay here because of the edge case described in |
1543 // http://crbug.com/675648. | 1549 // http://crbug.com/675648. |
1544 if (value != nullptr) { | 1550 if (value != nullptr) { |
1545 inputs[6] = value; | 1551 inputs[7] = value; |
1546 } | 1552 } |
1547 | 1553 |
1548 return *effect = *control = | 1554 return *effect = *control = |
1549 graph()->NewNode(common()->Call(call_descriptor), index, inputs); | 1555 graph()->NewNode(common()->Call(call_descriptor), index, inputs); |
1550 } | 1556 } |
1551 | 1557 |
1552 JSNativeContextSpecialization::ValueEffectControl | 1558 JSNativeContextSpecialization::ValueEffectControl |
1553 JSNativeContextSpecialization::BuildPropertyLoad( | 1559 JSNativeContextSpecialization::BuildPropertyLoad( |
1554 Node* receiver, Node* context, Node* frame_state, Node* effect, | 1560 Node* receiver, Node* context, Node* frame_state, Node* effect, |
1555 Node* control, Handle<Name> name, ZoneVector<Node*>* if_exceptions, | 1561 Node* control, Handle<Name> name, ZoneVector<Node*>* if_exceptions, |
(...skipping 840 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2396 return jsgraph()->javascript(); | 2402 return jsgraph()->javascript(); |
2397 } | 2403 } |
2398 | 2404 |
2399 SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const { | 2405 SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const { |
2400 return jsgraph()->simplified(); | 2406 return jsgraph()->simplified(); |
2401 } | 2407 } |
2402 | 2408 |
2403 } // namespace compiler | 2409 } // namespace compiler |
2404 } // namespace internal | 2410 } // namespace internal |
2405 } // namespace v8 | 2411 } // namespace v8 |
OLD | NEW |