Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Side by Side Diff: src/arm/full-codegen-arm.cc

Issue 6461017: ARM: Add type-feedback recording for compare... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/arm/constants-arm.h ('k') | src/arm/ic-arm.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 27 matching lines...) Expand all
38 #include "scopes.h" 38 #include "scopes.h"
39 #include "stub-cache.h" 39 #include "stub-cache.h"
40 40
41 #include "arm/code-stubs-arm.h" 41 #include "arm/code-stubs-arm.h"
42 42
43 namespace v8 { 43 namespace v8 {
44 namespace internal { 44 namespace internal {
45 45
46 #define __ ACCESS_MASM(masm_) 46 #define __ ACCESS_MASM(masm_)
47 47
48
49 // A patch site is a location in the code which it is possible to patch. This
50 // class has a number of methods to emit the code which is patchable and the
51 // method EmitPatchInfo to record a marker back to the patchable code. This
52 // marker is a cmp rx, #yyy instruction, and x * 0x00000fff + yyy (raw 12 bit
53 // immediate value is used) is the delta from the pc to the first instruction of
54 // the patchable code.
55 class JumpPatchSite BASE_EMBEDDED {
56 public:
57 explicit JumpPatchSite(MacroAssembler* masm) : masm_(masm) {
58 #ifdef DEBUG
59 info_emitted_ = false;
60 #endif
61 }
62
63 ~JumpPatchSite() {
64 ASSERT(patch_site_.is_bound() == info_emitted_);
65 }
66
67 // When initially emitting this ensure that a jump is always generated to skip
68 // the inlined smi code.
69 void EmitJumpIfNotSmi(Register reg, Label* target) {
70 ASSERT(!patch_site_.is_bound() && !info_emitted_);
71 __ bind(&patch_site_);
72 __ cmp(reg, Operand(reg));
73 // Don't use b(al, ...) as that might emit the constant pool right after the
74 // branch. After patching when the branch is no longer unconditional
75 // execution can continue into the constant pool.
76 __ b(eq, target); // Always taken before patched.
77 }
78
79 // When initially emitting this ensure that a jump is never generated to skip
80 // the inlined smi code.
81 void EmitJumpIfSmi(Register reg, Label* target) {
82 ASSERT(!patch_site_.is_bound() && !info_emitted_);
83 __ bind(&patch_site_);
84 __ cmp(reg, Operand(reg));
85 __ b(ne, target); // Never taken before patched.
86 }
87
88 void EmitPatchInfo() {
89 int delta_to_patch_site = masm_->InstructionsGeneratedSince(&patch_site_);
90 Register reg;
91 reg.set_code(delta_to_patch_site / kOff12Mask);
92 __ cmp_raw_immediate(reg, delta_to_patch_site % kOff12Mask);
93 #ifdef DEBUG
94 info_emitted_ = true;
95 #endif
96 }
97
98 bool is_bound() const { return patch_site_.is_bound(); }
99
100 private:
101 MacroAssembler* masm_;
102 Label patch_site_;
103 #ifdef DEBUG
104 bool info_emitted_;
105 #endif
106 };
107
108
48 // Generate code for a JS function. On entry to the function the receiver 109 // Generate code for a JS function. On entry to the function the receiver
49 // and arguments have been pushed on the stack left to right. The actual 110 // and arguments have been pushed on the stack left to right. The actual
50 // argument count matches the formal parameter count expected by the 111 // argument count matches the formal parameter count expected by the
51 // function. 112 // function.
52 // 113 //
53 // The live registers are: 114 // The live registers are:
54 // o r1: the JS function object being called (ie, ourselves) 115 // o r1: the JS function object being called (ie, ourselves)
55 // o cp: our context 116 // o cp: our context
56 // o fp: our caller's frame pointer 117 // o fp: our caller's frame pointer
57 // o sp: stack pointer 118 // o sp: stack pointer
(...skipping 687 matching lines...) Expand 10 before | Expand all | Expand 10 after
745 Comment cmnt(masm_, "[ Case comparison"); 806 Comment cmnt(masm_, "[ Case comparison");
746 __ bind(&next_test); 807 __ bind(&next_test);
747 next_test.Unuse(); 808 next_test.Unuse();
748 809
749 // Compile the label expression. 810 // Compile the label expression.
750 VisitForAccumulatorValue(clause->label()); 811 VisitForAccumulatorValue(clause->label());
751 812
752 // Perform the comparison as if via '==='. 813 // Perform the comparison as if via '==='.
753 __ ldr(r1, MemOperand(sp, 0)); // Switch value. 814 __ ldr(r1, MemOperand(sp, 0)); // Switch value.
754 bool inline_smi_code = ShouldInlineSmiCase(Token::EQ_STRICT); 815 bool inline_smi_code = ShouldInlineSmiCase(Token::EQ_STRICT);
816 JumpPatchSite patch_site(masm_);
755 if (inline_smi_code) { 817 if (inline_smi_code) {
756 Label slow_case; 818 Label slow_case;
757 __ orr(r2, r1, r0); 819 __ orr(r2, r1, r0);
758 __ tst(r2, Operand(kSmiTagMask)); 820 patch_site.EmitJumpIfNotSmi(r2, &slow_case);
759 __ b(ne, &slow_case); 821
760 __ cmp(r1, r0); 822 __ cmp(r1, r0);
761 __ b(ne, &next_test); 823 __ b(ne, &next_test);
762 __ Drop(1); // Switch value is no longer needed. 824 __ Drop(1); // Switch value is no longer needed.
763 __ b(clause->body_target()->entry_label()); 825 __ b(clause->body_target()->entry_label());
764 __ bind(&slow_case); 826 __ bind(&slow_case);
765 } 827 }
766 828
767 CompareFlags flags = inline_smi_code 829 // Record position before stub call for type feedback.
768 ? NO_SMI_COMPARE_IN_STUB 830 SetSourcePosition(clause->position());
769 : NO_COMPARE_FLAGS; 831 Handle<Code> ic = CompareIC::GetUninitialized(Token::EQ_STRICT);
770 CompareStub stub(eq, true, flags, r1, r0); 832 EmitCallIC(ic, &patch_site);
771 __ CallStub(&stub); 833 __ cmp(r0, Operand(0));
772 __ cmp(r0, Operand(0, RelocInfo::NONE));
773 __ b(ne, &next_test); 834 __ b(ne, &next_test);
774 __ Drop(1); // Switch value is no longer needed. 835 __ Drop(1); // Switch value is no longer needed.
775 __ b(clause->body_target()->entry_label()); 836 __ b(clause->body_target()->entry_label());
776 } 837 }
777 838
778 // Discard the test value and jump to the default if present, otherwise to 839 // Discard the test value and jump to the default if present, otherwise to
779 // the end of the statement. 840 // the end of the statement.
780 __ bind(&next_test); 841 __ bind(&next_test);
781 __ Drop(1); // Switch value is no longer needed. 842 __ Drop(1); // Switch value is no longer needed.
782 if (default_clause == NULL) { 843 if (default_clause == NULL) {
(...skipping 2720 matching lines...) Expand 10 before | Expand all | Expand 10 after
3503 cond = ge; 3564 cond = ge;
3504 __ pop(r1); 3565 __ pop(r1);
3505 break; 3566 break;
3506 case Token::IN: 3567 case Token::IN:
3507 case Token::INSTANCEOF: 3568 case Token::INSTANCEOF:
3508 default: 3569 default:
3509 UNREACHABLE(); 3570 UNREACHABLE();
3510 } 3571 }
3511 3572
3512 bool inline_smi_code = ShouldInlineSmiCase(op); 3573 bool inline_smi_code = ShouldInlineSmiCase(op);
3574 JumpPatchSite patch_site(masm_);
3513 if (inline_smi_code) { 3575 if (inline_smi_code) {
3514 Label slow_case; 3576 Label slow_case;
3515 __ orr(r2, r0, Operand(r1)); 3577 __ orr(r2, r0, Operand(r1));
3516 __ JumpIfNotSmi(r2, &slow_case); 3578 patch_site.EmitJumpIfNotSmi(r2, &slow_case);
3517 __ cmp(r1, r0); 3579 __ cmp(r1, r0);
3518 Split(cond, if_true, if_false, NULL); 3580 Split(cond, if_true, if_false, NULL);
3519 __ bind(&slow_case); 3581 __ bind(&slow_case);
3520 } 3582 }
3521 CompareFlags flags = inline_smi_code 3583
3522 ? NO_SMI_COMPARE_IN_STUB 3584 // Record position and call the compare IC.
3523 : NO_COMPARE_FLAGS; 3585 SetSourcePosition(expr->position());
3524 CompareStub stub(cond, strict, flags, r1, r0); 3586 Handle<Code> ic = CompareIC::GetUninitialized(op);
3525 __ CallStub(&stub); 3587 EmitCallIC(ic, &patch_site);
3526 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); 3588 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
3527 __ cmp(r0, Operand(0, RelocInfo::NONE)); 3589 __ cmp(r0, Operand(0));
3528 Split(cond, if_true, if_false, fall_through); 3590 Split(cond, if_true, if_false, fall_through);
3529 } 3591 }
3530 } 3592 }
3531 3593
3532 // Convert the result of the comparison into one expected for this 3594 // Convert the result of the comparison into one expected for this
3533 // expression's context. 3595 // expression's context.
3534 context()->Plug(if_true, if_false); 3596 context()->Plug(if_true, if_false);
3535 } 3597 }
3536 3598
3537 3599
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
3584 } 3646 }
3585 3647
3586 3648
3587 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, RelocInfo::Mode mode) { 3649 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, RelocInfo::Mode mode) {
3588 ASSERT(mode == RelocInfo::CODE_TARGET || 3650 ASSERT(mode == RelocInfo::CODE_TARGET ||
3589 mode == RelocInfo::CODE_TARGET_CONTEXT); 3651 mode == RelocInfo::CODE_TARGET_CONTEXT);
3590 __ Call(ic, mode); 3652 __ Call(ic, mode);
3591 } 3653 }
3592 3654
3593 3655
3656 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, JumpPatchSite* patch_site) {
3657 __ Call(ic, RelocInfo::CODE_TARGET);
3658 if (patch_site != NULL && patch_site->is_bound()) {
3659 patch_site->EmitPatchInfo();
3660 } else {
3661 __ nop(); // Signals no inlined code.
3662 }
3663 }
3664
3665
3594 void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) { 3666 void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) {
3595 ASSERT_EQ(POINTER_SIZE_ALIGN(frame_offset), frame_offset); 3667 ASSERT_EQ(POINTER_SIZE_ALIGN(frame_offset), frame_offset);
3596 __ str(value, MemOperand(fp, frame_offset)); 3668 __ str(value, MemOperand(fp, frame_offset));
3597 } 3669 }
3598 3670
3599 3671
3600 void FullCodeGenerator::LoadContextField(Register dst, int context_index) { 3672 void FullCodeGenerator::LoadContextField(Register dst, int context_index) {
3601 __ ldr(dst, ContextOperand(cp, context_index)); 3673 __ ldr(dst, ContextOperand(cp, context_index));
3602 } 3674 }
3603 3675
(...skipping 24 matching lines...) Expand all
3628 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. 3700 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value.
3629 __ add(pc, r1, Operand(masm_->CodeObject())); 3701 __ add(pc, r1, Operand(masm_->CodeObject()));
3630 } 3702 }
3631 3703
3632 3704
3633 #undef __ 3705 #undef __
3634 3706
3635 } } // namespace v8::internal 3707 } } // namespace v8::internal
3636 3708
3637 #endif // V8_TARGET_ARCH_ARM 3709 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/constants-arm.h ('k') | src/arm/ic-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698