| 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 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 154 // Monormorphic string access (ignoring the fact that there are multiple | 154 // Monormorphic string access (ignoring the fact that there are multiple |
| 155 // String maps). | 155 // String maps). |
| 156 receiver = effect = graph()->NewNode(simplified()->CheckString(), | 156 receiver = effect = graph()->NewNode(simplified()->CheckString(), |
| 157 receiver, effect, control); | 157 receiver, effect, control); |
| 158 } else if (HasOnlyNumberMaps(access_info.receiver_maps())) { | 158 } else if (HasOnlyNumberMaps(access_info.receiver_maps())) { |
| 159 // Monomorphic number access (we also deal with Smis here). | 159 // Monomorphic number access (we also deal with Smis here). |
| 160 receiver = effect = graph()->NewNode(simplified()->CheckNumber(), | 160 receiver = effect = graph()->NewNode(simplified()->CheckNumber(), |
| 161 receiver, effect, control); | 161 receiver, effect, control); |
| 162 } else { | 162 } else { |
| 163 // Monomorphic property access. | 163 // Monomorphic property access. |
| 164 effect = BuildCheckHeapObject(receiver, effect, control); | 164 receiver = effect = graph()->NewNode(simplified()->CheckHeapObject(), |
| 165 receiver, effect, control); |
| 165 effect = BuildCheckMaps(receiver, effect, control, | 166 effect = BuildCheckMaps(receiver, effect, control, |
| 166 access_info.receiver_maps()); | 167 access_info.receiver_maps()); |
| 167 } | 168 } |
| 168 | 169 |
| 169 // Generate the actual property access. | 170 // Generate the actual property access. |
| 170 ValueEffectControl continuation = | 171 ValueEffectControl continuation = |
| 171 BuildPropertyAccess(receiver, value, context, frame_state_lazy, effect, | 172 BuildPropertyAccess(receiver, value, context, frame_state_lazy, effect, |
| 172 control, name, access_info, access_mode); | 173 control, name, access_info, access_mode); |
| 173 value = continuation.value(); | 174 value = continuation.value(); |
| 174 effect = continuation.effect(); | 175 effect = continuation.effect(); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 192 // Ensure that {receiver} is a heap object. | 193 // Ensure that {receiver} is a heap object. |
| 193 Node* receiverissmi_control = nullptr; | 194 Node* receiverissmi_control = nullptr; |
| 194 Node* receiverissmi_effect = effect; | 195 Node* receiverissmi_effect = effect; |
| 195 if (receiverissmi_possible) { | 196 if (receiverissmi_possible) { |
| 196 Node* check = graph()->NewNode(simplified()->ObjectIsSmi(), receiver); | 197 Node* check = graph()->NewNode(simplified()->ObjectIsSmi(), receiver); |
| 197 Node* branch = graph()->NewNode(common()->Branch(), check, control); | 198 Node* branch = graph()->NewNode(common()->Branch(), check, control); |
| 198 control = graph()->NewNode(common()->IfFalse(), branch); | 199 control = graph()->NewNode(common()->IfFalse(), branch); |
| 199 receiverissmi_control = graph()->NewNode(common()->IfTrue(), branch); | 200 receiverissmi_control = graph()->NewNode(common()->IfTrue(), branch); |
| 200 receiverissmi_effect = effect; | 201 receiverissmi_effect = effect; |
| 201 } else { | 202 } else { |
| 202 effect = BuildCheckHeapObject(receiver, effect, control); | 203 receiver = effect = graph()->NewNode(simplified()->CheckHeapObject(), |
| 204 receiver, effect, control); |
| 203 } | 205 } |
| 204 | 206 |
| 205 // Load the {receiver} map. The resulting effect is the dominating effect | 207 // Load the {receiver} map. The resulting effect is the dominating effect |
| 206 // for all (polymorphic) branches. | 208 // for all (polymorphic) branches. |
| 207 Node* receiver_map = effect = | 209 Node* receiver_map = effect = |
| 208 graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()), | 210 graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()), |
| 209 receiver, effect, control); | 211 receiver, effect, control); |
| 210 | 212 |
| 211 // Generate code for the various different property access patterns. | 213 // Generate code for the various different property access patterns. |
| 212 Node* fallthrough_control = control; | 214 Node* fallthrough_control = control; |
| (...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 500 } | 502 } |
| 501 } | 503 } |
| 502 | 504 |
| 503 // Install dependencies on the relevant prototype maps. | 505 // Install dependencies on the relevant prototype maps. |
| 504 for (Handle<Map> prototype_map : prototype_maps) { | 506 for (Handle<Map> prototype_map : prototype_maps) { |
| 505 dependencies()->AssumeMapStable(prototype_map); | 507 dependencies()->AssumeMapStable(prototype_map); |
| 506 } | 508 } |
| 507 } | 509 } |
| 508 | 510 |
| 509 // Ensure that {receiver} is a heap object. | 511 // Ensure that {receiver} is a heap object. |
| 510 effect = BuildCheckHeapObject(receiver, effect, control); | 512 receiver = effect = graph()->NewNode(simplified()->CheckHeapObject(), |
| 513 receiver, effect, control); |
| 511 | 514 |
| 512 // Check for the monomorphic case. | 515 // Check for the monomorphic case. |
| 513 if (access_infos.size() == 1) { | 516 if (access_infos.size() == 1) { |
| 514 ElementAccessInfo access_info = access_infos.front(); | 517 ElementAccessInfo access_info = access_infos.front(); |
| 515 | 518 |
| 516 // Perform possible elements kind transitions. | 519 // Perform possible elements kind transitions. |
| 517 for (auto transition : access_info.transitions()) { | 520 for (auto transition : access_info.transitions()) { |
| 518 Handle<Map> const transition_source = transition.first; | 521 Handle<Map> const transition_source = transition.first; |
| 519 Handle<Map> const transition_target = transition.second; | 522 Handle<Map> const transition_target = transition.second; |
| 520 effect = graph()->NewNode( | 523 effect = graph()->NewNode( |
| (...skipping 921 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1442 inputs[0] = receiver; | 1445 inputs[0] = receiver; |
| 1443 for (int i = 0; i < map_input_count; ++i) { | 1446 for (int i = 0; i < map_input_count; ++i) { |
| 1444 inputs[1 + i] = jsgraph()->HeapConstant(maps[i]); | 1447 inputs[1 + i] = jsgraph()->HeapConstant(maps[i]); |
| 1445 } | 1448 } |
| 1446 inputs[input_count - 2] = effect; | 1449 inputs[input_count - 2] = effect; |
| 1447 inputs[input_count - 1] = control; | 1450 inputs[input_count - 1] = control; |
| 1448 return graph()->NewNode(simplified()->CheckMaps(map_input_count), input_count, | 1451 return graph()->NewNode(simplified()->CheckMaps(map_input_count), input_count, |
| 1449 inputs); | 1452 inputs); |
| 1450 } | 1453 } |
| 1451 | 1454 |
| 1452 Node* JSNativeContextSpecialization::BuildCheckHeapObject(Node* receiver, | |
| 1453 Node* effect, | |
| 1454 Node* control) { | |
| 1455 switch (receiver->opcode()) { | |
| 1456 case IrOpcode::kHeapConstant: | |
| 1457 case IrOpcode::kJSCreate: | |
| 1458 case IrOpcode::kJSCreateArguments: | |
| 1459 case IrOpcode::kJSCreateArray: | |
| 1460 case IrOpcode::kJSCreateClosure: | |
| 1461 case IrOpcode::kJSCreateIterResultObject: | |
| 1462 case IrOpcode::kJSCreateLiteralArray: | |
| 1463 case IrOpcode::kJSCreateLiteralObject: | |
| 1464 case IrOpcode::kJSCreateLiteralRegExp: | |
| 1465 case IrOpcode::kJSConvertReceiver: | |
| 1466 case IrOpcode::kJSToName: | |
| 1467 case IrOpcode::kJSToString: | |
| 1468 case IrOpcode::kJSToObject: | |
| 1469 case IrOpcode::kJSTypeOf: { | |
| 1470 return effect; | |
| 1471 } | |
| 1472 default: { | |
| 1473 return graph()->NewNode(simplified()->CheckHeapObject(), receiver, effect, | |
| 1474 control); | |
| 1475 } | |
| 1476 } | |
| 1477 } | |
| 1478 | |
| 1479 void JSNativeContextSpecialization::AssumePrototypesStable( | 1455 void JSNativeContextSpecialization::AssumePrototypesStable( |
| 1480 std::vector<Handle<Map>> const& receiver_maps, Handle<JSObject> holder) { | 1456 std::vector<Handle<Map>> const& receiver_maps, Handle<JSObject> holder) { |
| 1481 // Determine actual holder and perform prototype chain checks. | 1457 // Determine actual holder and perform prototype chain checks. |
| 1482 for (auto map : receiver_maps) { | 1458 for (auto map : receiver_maps) { |
| 1483 // Perform the implicit ToObject for primitives here. | 1459 // Perform the implicit ToObject for primitives here. |
| 1484 // Implemented according to ES6 section 7.3.2 GetV (V, P). | 1460 // Implemented according to ES6 section 7.3.2 GetV (V, P). |
| 1485 Handle<JSFunction> constructor; | 1461 Handle<JSFunction> constructor; |
| 1486 if (Map::GetConstructorFunction(map, native_context()) | 1462 if (Map::GetConstructorFunction(map, native_context()) |
| 1487 .ToHandle(&constructor)) { | 1463 .ToHandle(&constructor)) { |
| 1488 map = handle(constructor->initial_map(), isolate()); | 1464 map = handle(constructor->initial_map(), isolate()); |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1633 return jsgraph()->javascript(); | 1609 return jsgraph()->javascript(); |
| 1634 } | 1610 } |
| 1635 | 1611 |
| 1636 SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const { | 1612 SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const { |
| 1637 return jsgraph()->simplified(); | 1613 return jsgraph()->simplified(); |
| 1638 } | 1614 } |
| 1639 | 1615 |
| 1640 } // namespace compiler | 1616 } // namespace compiler |
| 1641 } // namespace internal | 1617 } // namespace internal |
| 1642 } // namespace v8 | 1618 } // namespace v8 |
| OLD | NEW |