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 |