| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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/ic.h" | 5 #include "src/ic/ic.h" |
| 6 | 6 |
| 7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
| 8 #include "src/api.h" | 8 #include "src/api.h" |
| 9 #include "src/arguments.h" | 9 #include "src/arguments.h" |
| 10 #include "src/base/bits.h" | 10 #include "src/base/bits.h" |
| (...skipping 528 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 539 OnTypeFeedbackChanged(isolate, host); | 539 OnTypeFeedbackChanged(isolate, host); |
| 540 } | 540 } |
| 541 | 541 |
| 542 | 542 |
| 543 void CompareIC::Clear(Isolate* isolate, Address address, Code* target, | 543 void CompareIC::Clear(Isolate* isolate, Address address, Code* target, |
| 544 Address constant_pool) { | 544 Address constant_pool) { |
| 545 DCHECK(CodeStub::GetMajorKey(target) == CodeStub::CompareIC); | 545 DCHECK(CodeStub::GetMajorKey(target) == CodeStub::CompareIC); |
| 546 CompareICStub stub(target->stub_key(), isolate); | 546 CompareICStub stub(target->stub_key(), isolate); |
| 547 // Only clear CompareICs that can retain objects. | 547 // Only clear CompareICs that can retain objects. |
| 548 if (stub.state() != CompareICState::KNOWN_RECEIVER) return; | 548 if (stub.state() != CompareICState::KNOWN_RECEIVER) return; |
| 549 SetTargetAtAddress(address, | 549 SetTargetAtAddress(address, GetRawUninitialized(isolate, stub.op()), |
| 550 GetRawUninitialized(isolate, stub.op(), stub.strength()), | |
| 551 constant_pool); | 550 constant_pool); |
| 552 PatchInlinedSmiCode(isolate, address, DISABLE_INLINED_SMI_CHECK); | 551 PatchInlinedSmiCode(isolate, address, DISABLE_INLINED_SMI_CHECK); |
| 553 } | 552 } |
| 554 | 553 |
| 555 | 554 |
| 556 // static | 555 // static |
| 557 Handle<Code> KeyedLoadIC::ChooseMegamorphicStub(Isolate* isolate, | 556 Handle<Code> KeyedLoadIC::ChooseMegamorphicStub(Isolate* isolate, |
| 558 ExtraICState extra_state) { | 557 ExtraICState extra_state) { |
| 559 if (FLAG_compiled_keyed_generic_loads) { | 558 if (FLAG_compiled_keyed_generic_loads) { |
| 560 return KeyedLoadGenericStub(isolate, LoadICState(extra_state)).GetCode(); | 559 return KeyedLoadGenericStub(isolate, LoadICState(extra_state)).GetCode(); |
| (...skipping 1935 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2496 Handle<AllocationSite> allocation_site, Handle<Object> left, | 2495 Handle<AllocationSite> allocation_site, Handle<Object> left, |
| 2497 Handle<Object> right) { | 2496 Handle<Object> right) { |
| 2498 BinaryOpICState state(isolate(), target()->extra_ic_state()); | 2497 BinaryOpICState state(isolate(), target()->extra_ic_state()); |
| 2499 | 2498 |
| 2500 // Compute the actual result using the builtin for the binary operation. | 2499 // Compute the actual result using the builtin for the binary operation. |
| 2501 Handle<Object> result; | 2500 Handle<Object> result; |
| 2502 switch (state.op()) { | 2501 switch (state.op()) { |
| 2503 default: | 2502 default: |
| 2504 UNREACHABLE(); | 2503 UNREACHABLE(); |
| 2505 case Token::ADD: | 2504 case Token::ADD: |
| 2506 ASSIGN_RETURN_ON_EXCEPTION( | 2505 ASSIGN_RETURN_ON_EXCEPTION(isolate(), result, |
| 2507 isolate(), result, | 2506 Object::Add(isolate(), left, right), Object); |
| 2508 Object::Add(isolate(), left, right, state.strength()), Object); | |
| 2509 break; | 2507 break; |
| 2510 case Token::SUB: | 2508 case Token::SUB: |
| 2511 ASSIGN_RETURN_ON_EXCEPTION( | 2509 ASSIGN_RETURN_ON_EXCEPTION( |
| 2512 isolate(), result, | 2510 isolate(), result, Object::Subtract(isolate(), left, right), Object); |
| 2513 Object::Subtract(isolate(), left, right, state.strength()), Object); | |
| 2514 break; | 2511 break; |
| 2515 case Token::MUL: | 2512 case Token::MUL: |
| 2516 ASSIGN_RETURN_ON_EXCEPTION( | 2513 ASSIGN_RETURN_ON_EXCEPTION( |
| 2517 isolate(), result, | 2514 isolate(), result, Object::Multiply(isolate(), left, right), Object); |
| 2518 Object::Multiply(isolate(), left, right, state.strength()), Object); | |
| 2519 break; | 2515 break; |
| 2520 case Token::DIV: | 2516 case Token::DIV: |
| 2521 ASSIGN_RETURN_ON_EXCEPTION( | 2517 ASSIGN_RETURN_ON_EXCEPTION( |
| 2522 isolate(), result, | 2518 isolate(), result, Object::Divide(isolate(), left, right), Object); |
| 2523 Object::Divide(isolate(), left, right, state.strength()), Object); | |
| 2524 break; | 2519 break; |
| 2525 case Token::MOD: | 2520 case Token::MOD: |
| 2526 ASSIGN_RETURN_ON_EXCEPTION( | 2521 ASSIGN_RETURN_ON_EXCEPTION( |
| 2527 isolate(), result, | 2522 isolate(), result, Object::Modulus(isolate(), left, right), Object); |
| 2528 Object::Modulus(isolate(), left, right, state.strength()), Object); | |
| 2529 break; | 2523 break; |
| 2530 case Token::BIT_OR: | 2524 case Token::BIT_OR: |
| 2531 ASSIGN_RETURN_ON_EXCEPTION( | 2525 ASSIGN_RETURN_ON_EXCEPTION( |
| 2532 isolate(), result, | 2526 isolate(), result, Object::BitwiseOr(isolate(), left, right), Object); |
| 2533 Object::BitwiseOr(isolate(), left, right, state.strength()), Object); | |
| 2534 break; | 2527 break; |
| 2535 case Token::BIT_AND: | 2528 case Token::BIT_AND: |
| 2536 ASSIGN_RETURN_ON_EXCEPTION( | 2529 ASSIGN_RETURN_ON_EXCEPTION(isolate(), result, |
| 2537 isolate(), result, | 2530 Object::BitwiseAnd(isolate(), left, right), |
| 2538 Object::BitwiseAnd(isolate(), left, right, state.strength()), Object); | 2531 Object); |
| 2539 break; | 2532 break; |
| 2540 case Token::BIT_XOR: | 2533 case Token::BIT_XOR: |
| 2541 ASSIGN_RETURN_ON_EXCEPTION( | 2534 ASSIGN_RETURN_ON_EXCEPTION(isolate(), result, |
| 2542 isolate(), result, | 2535 Object::BitwiseXor(isolate(), left, right), |
| 2543 Object::BitwiseXor(isolate(), left, right, state.strength()), Object); | 2536 Object); |
| 2544 break; | 2537 break; |
| 2545 case Token::SAR: | 2538 case Token::SAR: |
| 2546 ASSIGN_RETURN_ON_EXCEPTION( | 2539 ASSIGN_RETURN_ON_EXCEPTION(isolate(), result, |
| 2547 isolate(), result, | 2540 Object::ShiftRight(isolate(), left, right), |
| 2548 Object::ShiftRight(isolate(), left, right, state.strength()), Object); | 2541 Object); |
| 2549 break; | 2542 break; |
| 2550 case Token::SHR: | 2543 case Token::SHR: |
| 2551 ASSIGN_RETURN_ON_EXCEPTION( | 2544 ASSIGN_RETURN_ON_EXCEPTION( |
| 2552 isolate(), result, | 2545 isolate(), result, Object::ShiftRightLogical(isolate(), left, right), |
| 2553 Object::ShiftRightLogical(isolate(), left, right, state.strength()), | |
| 2554 Object); | 2546 Object); |
| 2555 break; | 2547 break; |
| 2556 case Token::SHL: | 2548 case Token::SHL: |
| 2557 ASSIGN_RETURN_ON_EXCEPTION( | 2549 ASSIGN_RETURN_ON_EXCEPTION( |
| 2558 isolate(), result, | 2550 isolate(), result, Object::ShiftLeft(isolate(), left, right), Object); |
| 2559 Object::ShiftLeft(isolate(), left, right, state.strength()), Object); | |
| 2560 break; | 2551 break; |
| 2561 } | 2552 } |
| 2562 | 2553 |
| 2563 // Do not try to update the target if the code was marked for lazy | 2554 // Do not try to update the target if the code was marked for lazy |
| 2564 // deoptimization. (Since we do not relocate addresses in these | 2555 // deoptimization. (Since we do not relocate addresses in these |
| 2565 // code objects, an attempt to access the target could fail.) | 2556 // code objects, an attempt to access the target could fail.) |
| 2566 if (AddressIsDeoptimizedCode()) { | 2557 if (AddressIsDeoptimizedCode()) { |
| 2567 return result; | 2558 return result; |
| 2568 } | 2559 } |
| 2569 | 2560 |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2645 Handle<Object> left = args.at<Object>(BinaryOpWithAllocationSiteStub::kLeft); | 2636 Handle<Object> left = args.at<Object>(BinaryOpWithAllocationSiteStub::kLeft); |
| 2646 Handle<Object> right = | 2637 Handle<Object> right = |
| 2647 args.at<Object>(BinaryOpWithAllocationSiteStub::kRight); | 2638 args.at<Object>(BinaryOpWithAllocationSiteStub::kRight); |
| 2648 BinaryOpIC ic(isolate); | 2639 BinaryOpIC ic(isolate); |
| 2649 Handle<Object> result; | 2640 Handle<Object> result; |
| 2650 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 2641 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
| 2651 isolate, result, ic.Transition(allocation_site, left, right)); | 2642 isolate, result, ic.Transition(allocation_site, left, right)); |
| 2652 return *result; | 2643 return *result; |
| 2653 } | 2644 } |
| 2654 | 2645 |
| 2655 | 2646 Code* CompareIC::GetRawUninitialized(Isolate* isolate, Token::Value op) { |
| 2656 Code* CompareIC::GetRawUninitialized(Isolate* isolate, Token::Value op, | 2647 CompareICStub stub(isolate, op, CompareICState::UNINITIALIZED, |
| 2657 Strength strength) { | |
| 2658 CompareICStub stub(isolate, op, strength, CompareICState::UNINITIALIZED, | |
| 2659 CompareICState::UNINITIALIZED, | 2648 CompareICState::UNINITIALIZED, |
| 2660 CompareICState::UNINITIALIZED); | 2649 CompareICState::UNINITIALIZED); |
| 2661 Code* code = NULL; | 2650 Code* code = NULL; |
| 2662 CHECK(stub.FindCodeInCache(&code)); | 2651 CHECK(stub.FindCodeInCache(&code)); |
| 2663 return code; | 2652 return code; |
| 2664 } | 2653 } |
| 2665 | 2654 |
| 2666 | 2655 Handle<Code> CompareIC::GetUninitialized(Isolate* isolate, Token::Value op) { |
| 2667 Handle<Code> CompareIC::GetUninitialized(Isolate* isolate, Token::Value op, | 2656 CompareICStub stub(isolate, op, CompareICState::UNINITIALIZED, |
| 2668 Strength strength) { | |
| 2669 CompareICStub stub(isolate, op, strength, CompareICState::UNINITIALIZED, | |
| 2670 CompareICState::UNINITIALIZED, | 2657 CompareICState::UNINITIALIZED, |
| 2671 CompareICState::UNINITIALIZED); | 2658 CompareICState::UNINITIALIZED); |
| 2672 return stub.GetCode(); | 2659 return stub.GetCode(); |
| 2673 } | 2660 } |
| 2674 | 2661 |
| 2675 | 2662 |
| 2676 Code* CompareIC::UpdateCaches(Handle<Object> x, Handle<Object> y) { | 2663 Code* CompareIC::UpdateCaches(Handle<Object> x, Handle<Object> y) { |
| 2677 HandleScope scope(isolate()); | 2664 HandleScope scope(isolate()); |
| 2678 CompareICStub old_stub(target()->stub_key(), isolate()); | 2665 CompareICStub old_stub(target()->stub_key(), isolate()); |
| 2679 CompareICState::State new_left = | 2666 CompareICState::State new_left = |
| 2680 CompareICState::NewInputState(old_stub.left(), x); | 2667 CompareICState::NewInputState(old_stub.left(), x); |
| 2681 CompareICState::State new_right = | 2668 CompareICState::State new_right = |
| 2682 CompareICState::NewInputState(old_stub.right(), y); | 2669 CompareICState::NewInputState(old_stub.right(), y); |
| 2683 CompareICState::State state = CompareICState::TargetState( | 2670 CompareICState::State state = CompareICState::TargetState( |
| 2684 old_stub.state(), old_stub.left(), old_stub.right(), op_, | 2671 old_stub.state(), old_stub.left(), old_stub.right(), op_, |
| 2685 HasInlinedSmiCode(address()), x, y); | 2672 HasInlinedSmiCode(address()), x, y); |
| 2686 CompareICStub stub(isolate(), op_, old_stub.strength(), new_left, new_right, | 2673 CompareICStub stub(isolate(), op_, new_left, new_right, state); |
| 2687 state); | |
| 2688 if (state == CompareICState::KNOWN_RECEIVER) { | 2674 if (state == CompareICState::KNOWN_RECEIVER) { |
| 2689 stub.set_known_map( | 2675 stub.set_known_map( |
| 2690 Handle<Map>(Handle<JSReceiver>::cast(x)->map(), isolate())); | 2676 Handle<Map>(Handle<JSReceiver>::cast(x)->map(), isolate())); |
| 2691 } | 2677 } |
| 2692 Handle<Code> new_target = stub.GetCode(); | 2678 Handle<Code> new_target = stub.GetCode(); |
| 2693 set_target(*new_target); | 2679 set_target(*new_target); |
| 2694 | 2680 |
| 2695 if (FLAG_trace_ic) { | 2681 if (FLAG_trace_ic) { |
| 2696 PrintF("[CompareIC in "); | 2682 PrintF("[CompareIC in "); |
| 2697 JavaScriptFrame::PrintTop(isolate(), stdout, false, true); | 2683 JavaScriptFrame::PrintTop(isolate(), stdout, false, true); |
| (...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2966 KeyedLoadICNexus nexus(vector, vector_slot); | 2952 KeyedLoadICNexus nexus(vector, vector_slot); |
| 2967 KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus); | 2953 KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus); |
| 2968 ic.UpdateState(receiver, key); | 2954 ic.UpdateState(receiver, key); |
| 2969 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key)); | 2955 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key)); |
| 2970 } | 2956 } |
| 2971 | 2957 |
| 2972 return *result; | 2958 return *result; |
| 2973 } | 2959 } |
| 2974 } // namespace internal | 2960 } // namespace internal |
| 2975 } // namespace v8 | 2961 } // namespace v8 |
| OLD | NEW |