| 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/effect-control-linearizer.h" | 5 #include "src/compiler/effect-control-linearizer.h" |
| 6 | 6 |
| 7 #include "src/code-factory.h" | 7 #include "src/code-factory.h" |
| 8 #include "src/compiler/access-builder.h" | 8 #include "src/compiler/access-builder.h" |
| 9 #include "src/compiler/js-graph.h" | 9 #include "src/compiler/js-graph.h" |
| 10 #include "src/compiler/linkage.h" | 10 #include "src/compiler/linkage.h" |
| (...skipping 2429 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2440 graph()->NewNode(machine()->Word32And(), value, | 2440 graph()->NewNode(machine()->Word32And(), value, |
| 2441 jsgraph()->Int32Constant(String::kMaxUtf16CodeUnit)); | 2441 jsgraph()->Int32Constant(String::kMaxUtf16CodeUnit)); |
| 2442 | 2442 |
| 2443 // Check if the {code} is a one-byte char code. | 2443 // Check if the {code} is a one-byte char code. |
| 2444 Node* check0 = | 2444 Node* check0 = |
| 2445 graph()->NewNode(machine()->Int32LessThanOrEqual(), code, | 2445 graph()->NewNode(machine()->Int32LessThanOrEqual(), code, |
| 2446 jsgraph()->Int32Constant(String::kMaxOneByteCharCode)); | 2446 jsgraph()->Int32Constant(String::kMaxOneByteCharCode)); |
| 2447 Node* branch0 = | 2447 Node* branch0 = |
| 2448 graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control); | 2448 graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control); |
| 2449 | 2449 |
| 2450 Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0); |
| 2451 Node* efalse0 = effect; |
| 2452 |
| 2450 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0); | 2453 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0); |
| 2451 Node* etrue0 = effect; | 2454 Node* etrue0 = effect; |
| 2452 Node* vtrue0; | 2455 |
| 2456 // Load the isolate wide single character string cache. |
| 2457 Node* cache = |
| 2458 jsgraph()->HeapConstant(factory()->single_character_string_cache()); |
| 2459 |
| 2460 // Compute the {cache} index for {code}. |
| 2461 Node* index = machine()->Is32() |
| 2462 ? code |
| 2463 : graph()->NewNode(machine()->ChangeUint32ToUint64(), code); |
| 2464 |
| 2465 // Check if we have an entry for the {code} in the single character string |
| 2466 // cache already. |
| 2467 Node* entry = etrue0 = graph()->NewNode( |
| 2468 simplified()->LoadElement(AccessBuilder::ForFixedArrayElement()), cache, |
| 2469 index, etrue0, if_true0); |
| 2470 |
| 2471 Node* check1 = graph()->NewNode(machine()->WordEqual(), entry, |
| 2472 jsgraph()->UndefinedConstant()); |
| 2473 Node* branch1 = |
| 2474 graph()->NewNode(common()->Branch(BranchHint::kFalse), check1, if_true0); |
| 2475 |
| 2476 // Use the {entry} from the {cache}. |
| 2477 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1); |
| 2478 Node* efalse1 = etrue0; |
| 2479 Node* vfalse1 = entry; |
| 2480 |
| 2481 // Let %StringFromCharCode handle this case. |
| 2482 // TODO(turbofan): At some point we may consider adding a stub for this |
| 2483 // deferred case, so that we don't need to call to C++ here. |
| 2484 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); |
| 2485 Node* etrue1 = etrue0; |
| 2486 Node* vtrue1; |
| 2453 { | 2487 { |
| 2454 // Load the isolate wide single character string cache. | 2488 if_true1 = graph()->NewNode(common()->Merge(2), if_true1, if_false0); |
| 2455 Node* cache = | 2489 etrue1 = |
| 2456 jsgraph()->HeapConstant(factory()->single_character_string_cache()); | 2490 graph()->NewNode(common()->EffectPhi(2), etrue1, efalse0, if_true1); |
| 2457 | 2491 Operator::Properties properties = Operator::kNoDeopt | Operator::kNoThrow; |
| 2458 // Compute the {cache} index for {code}. | 2492 Runtime::FunctionId id = Runtime::kStringCharFromCode; |
| 2459 Node* index = | 2493 CallDescriptor const* desc = Linkage::GetRuntimeCallDescriptor( |
| 2460 machine()->Is32() ? code : graph()->NewNode( | 2494 graph()->zone(), id, 1, properties, CallDescriptor::kNoFlags); |
| 2461 machine()->ChangeUint32ToUint64(), code); | 2495 vtrue1 = etrue1 = graph()->NewNode( |
| 2462 | 2496 common()->Call(desc), jsgraph()->CEntryStubConstant(1), |
| 2463 // Check if we have an entry for the {code} in the single character string | 2497 ChangeInt32ToSmi(code), |
| 2464 // cache already. | 2498 jsgraph()->ExternalConstant(ExternalReference(id, isolate())), |
| 2465 Node* entry = etrue0 = graph()->NewNode( | 2499 jsgraph()->Int32Constant(1), jsgraph()->NoContextConstant(), etrue1, |
| 2466 simplified()->LoadElement(AccessBuilder::ForFixedArrayElement()), cache, | 2500 if_true1); |
| 2467 index, etrue0, if_true0); | |
| 2468 | |
| 2469 Node* check1 = graph()->NewNode(machine()->WordEqual(), entry, | |
| 2470 jsgraph()->UndefinedConstant()); | |
| 2471 Node* branch1 = graph()->NewNode(common()->Branch(BranchHint::kFalse), | |
| 2472 check1, if_true0); | |
| 2473 | |
| 2474 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); | |
| 2475 Node* etrue1 = etrue0; | |
| 2476 Node* vtrue1; | |
| 2477 { | |
| 2478 // Allocate a new SeqOneByteString for {code}. | |
| 2479 vtrue1 = etrue1 = graph()->NewNode( | |
| 2480 simplified()->Allocate(NOT_TENURED), | |
| 2481 jsgraph()->Int32Constant(SeqOneByteString::SizeFor(1)), etrue1, | |
| 2482 if_true1); | |
| 2483 etrue1 = graph()->NewNode( | |
| 2484 simplified()->StoreField(AccessBuilder::ForMap()), vtrue1, | |
| 2485 jsgraph()->HeapConstant(factory()->one_byte_string_map()), etrue1, | |
| 2486 if_true1); | |
| 2487 etrue1 = graph()->NewNode( | |
| 2488 simplified()->StoreField(AccessBuilder::ForNameHashField()), vtrue1, | |
| 2489 jsgraph()->IntPtrConstant(Name::kEmptyHashField), etrue1, if_true1); | |
| 2490 etrue1 = graph()->NewNode( | |
| 2491 simplified()->StoreField(AccessBuilder::ForStringLength()), vtrue1, | |
| 2492 jsgraph()->SmiConstant(1), etrue1, if_true1); | |
| 2493 etrue1 = graph()->NewNode( | |
| 2494 machine()->Store(StoreRepresentation(MachineRepresentation::kWord8, | |
| 2495 kNoWriteBarrier)), | |
| 2496 vtrue1, jsgraph()->IntPtrConstant(SeqOneByteString::kHeaderSize - | |
| 2497 kHeapObjectTag), | |
| 2498 code, etrue1, if_true1); | |
| 2499 | |
| 2500 // Remember it in the {cache}. | |
| 2501 etrue1 = graph()->NewNode( | |
| 2502 simplified()->StoreElement(AccessBuilder::ForFixedArrayElement()), | |
| 2503 cache, index, vtrue1, etrue1, if_true1); | |
| 2504 } | |
| 2505 | |
| 2506 // Use the {entry} from the {cache}. | |
| 2507 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1); | |
| 2508 Node* efalse1 = etrue0; | |
| 2509 Node* vfalse1 = entry; | |
| 2510 | |
| 2511 if_true0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1); | |
| 2512 etrue0 = | |
| 2513 graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, if_true0); | |
| 2514 vtrue0 = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2), | |
| 2515 vtrue1, vfalse1, if_true0); | |
| 2516 } | 2501 } |
| 2517 | 2502 |
| 2518 Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0); | 2503 control = graph()->NewNode(common()->Merge(2), if_true1, if_false1); |
| 2519 Node* efalse0 = effect; | 2504 effect = graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, control); |
| 2520 Node* vfalse0; | |
| 2521 { | |
| 2522 // Allocate a new SeqTwoByteString for {code}. | |
| 2523 vfalse0 = efalse0 = | |
| 2524 graph()->NewNode(simplified()->Allocate(NOT_TENURED), | |
| 2525 jsgraph()->Int32Constant(SeqTwoByteString::SizeFor(1)), | |
| 2526 efalse0, if_false0); | |
| 2527 efalse0 = graph()->NewNode( | |
| 2528 simplified()->StoreField(AccessBuilder::ForMap()), vfalse0, | |
| 2529 jsgraph()->HeapConstant(factory()->string_map()), efalse0, if_false0); | |
| 2530 efalse0 = graph()->NewNode( | |
| 2531 simplified()->StoreField(AccessBuilder::ForNameHashField()), vfalse0, | |
| 2532 jsgraph()->IntPtrConstant(Name::kEmptyHashField), efalse0, if_false0); | |
| 2533 efalse0 = graph()->NewNode( | |
| 2534 simplified()->StoreField(AccessBuilder::ForStringLength()), vfalse0, | |
| 2535 jsgraph()->SmiConstant(1), efalse0, if_false0); | |
| 2536 efalse0 = graph()->NewNode( | |
| 2537 machine()->Store(StoreRepresentation(MachineRepresentation::kWord16, | |
| 2538 kNoWriteBarrier)), | |
| 2539 vfalse0, jsgraph()->IntPtrConstant(SeqTwoByteString::kHeaderSize - | |
| 2540 kHeapObjectTag), | |
| 2541 code, efalse0, if_false0); | |
| 2542 } | |
| 2543 | |
| 2544 control = graph()->NewNode(common()->Merge(2), if_true0, if_false0); | |
| 2545 effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control); | |
| 2546 value = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2), | 2505 value = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2), |
| 2547 vtrue0, vfalse0, control); | 2506 vtrue1, vfalse1, control); |
| 2548 | 2507 |
| 2549 return ValueEffectControl(value, effect, control); | 2508 return ValueEffectControl(value, effect, control); |
| 2550 } | 2509 } |
| 2551 | 2510 |
| 2552 EffectControlLinearizer::ValueEffectControl | 2511 EffectControlLinearizer::ValueEffectControl |
| 2553 EffectControlLinearizer::LowerStringFromCodePoint(Node* node, Node* effect, | 2512 EffectControlLinearizer::LowerStringFromCodePoint(Node* node, Node* effect, |
| 2554 Node* control) { | 2513 Node* control) { |
| 2555 Node* value = node->InputAt(0); | 2514 Node* value = node->InputAt(0); |
| 2556 Node* code = value; | 2515 Node* code = value; |
| 2557 | 2516 |
| (...skipping 1126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3684 isolate(), graph()->zone(), callable.descriptor(), 0, flags, | 3643 isolate(), graph()->zone(), callable.descriptor(), 0, flags, |
| 3685 Operator::kEliminatable); | 3644 Operator::kEliminatable); |
| 3686 to_number_operator_.set(common()->Call(desc)); | 3645 to_number_operator_.set(common()->Call(desc)); |
| 3687 } | 3646 } |
| 3688 return to_number_operator_.get(); | 3647 return to_number_operator_.get(); |
| 3689 } | 3648 } |
| 3690 | 3649 |
| 3691 } // namespace compiler | 3650 } // namespace compiler |
| 3692 } // namespace internal | 3651 } // namespace internal |
| 3693 } // namespace v8 | 3652 } // namespace v8 |
| OLD | NEW |