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

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

Issue 7273066: Simplify EmitCallIC. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 9 years, 5 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 | « no previous file | src/full-codegen.h » ('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 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
85 // When initially emitting this ensure that a jump is never generated to skip 85 // When initially emitting this ensure that a jump is never generated to skip
86 // the inlined smi code. 86 // the inlined smi code.
87 void EmitJumpIfSmi(Register reg, Label* target) { 87 void EmitJumpIfSmi(Register reg, Label* target) {
88 ASSERT(!patch_site_.is_bound() && !info_emitted_); 88 ASSERT(!patch_site_.is_bound() && !info_emitted_);
89 __ bind(&patch_site_); 89 __ bind(&patch_site_);
90 __ cmp(reg, Operand(reg)); 90 __ cmp(reg, Operand(reg));
91 __ b(ne, target); // Never taken before patched. 91 __ b(ne, target); // Never taken before patched.
92 } 92 }
93 93
94 void EmitPatchInfo() { 94 void EmitPatchInfo() {
95 int delta_to_patch_site = masm_->InstructionsGeneratedSince(&patch_site_); 95 if (patch_site_.is_bound()) {
96 Register reg; 96 int delta_to_patch_site = masm_->InstructionsGeneratedSince(&patch_site_);
97 reg.set_code(delta_to_patch_site / kOff12Mask); 97 Register reg;
98 __ cmp_raw_immediate(reg, delta_to_patch_site % kOff12Mask); 98 reg.set_code(delta_to_patch_site / kOff12Mask);
99 __ cmp_raw_immediate(reg, delta_to_patch_site % kOff12Mask);
99 #ifdef DEBUG 100 #ifdef DEBUG
100 info_emitted_ = true; 101 info_emitted_ = true;
101 #endif 102 #endif
103 } else {
104 __ nop(); // Signals no inlined code.
105 }
102 } 106 }
103 107
104 bool is_bound() const { return patch_site_.is_bound(); }
105
106 private: 108 private:
107 MacroAssembler* masm_; 109 MacroAssembler* masm_;
108 Label patch_site_; 110 Label patch_site_;
109 #ifdef DEBUG 111 #ifdef DEBUG
110 bool info_emitted_; 112 bool info_emitted_;
111 #endif 113 #endif
112 }; 114 };
113 115
114 116
115 // Generate code for a JS function. On entry to the function the receiver 117 // Generate code for a JS function. On entry to the function the receiver
(...skipping 737 matching lines...) Expand 10 before | Expand all | Expand 10 after
853 __ cmp(r1, r0); 855 __ cmp(r1, r0);
854 __ b(ne, &next_test); 856 __ b(ne, &next_test);
855 __ Drop(1); // Switch value is no longer needed. 857 __ Drop(1); // Switch value is no longer needed.
856 __ b(clause->body_target()); 858 __ b(clause->body_target());
857 __ bind(&slow_case); 859 __ bind(&slow_case);
858 } 860 }
859 861
860 // Record position before stub call for type feedback. 862 // Record position before stub call for type feedback.
861 SetSourcePosition(clause->position()); 863 SetSourcePosition(clause->position());
862 Handle<Code> ic = CompareIC::GetUninitialized(Token::EQ_STRICT); 864 Handle<Code> ic = CompareIC::GetUninitialized(Token::EQ_STRICT);
863 EmitCallIC(ic, &patch_site, clause->CompareId()); 865 EmitCallIC(ic, RelocInfo::CODE_TARGET, clause->CompareId());
866 patch_site.EmitPatchInfo();
864 867
865 __ cmp(r0, Operand(0)); 868 __ cmp(r0, Operand(0));
866 __ b(ne, &next_test); 869 __ b(ne, &next_test);
867 __ Drop(1); // Switch value is no longer needed. 870 __ Drop(1); // Switch value is no longer needed.
868 __ b(clause->body_target()); 871 __ b(clause->body_target());
869 } 872 }
870 873
871 // Discard the test value and jump to the default if present, otherwise to 874 // Discard the test value and jump to the default if present, otherwise to
872 // the end of the statement. 875 // the end of the statement.
873 __ bind(&next_test); 876 __ bind(&next_test);
(...skipping 808 matching lines...) Expand 10 before | Expand all | Expand 10 after
1682 __ pop(left); 1685 __ pop(left);
1683 1686
1684 // Perform combined smi check on both operands. 1687 // Perform combined smi check on both operands.
1685 __ orr(scratch1, left, Operand(right)); 1688 __ orr(scratch1, left, Operand(right));
1686 STATIC_ASSERT(kSmiTag == 0); 1689 STATIC_ASSERT(kSmiTag == 0);
1687 JumpPatchSite patch_site(masm_); 1690 JumpPatchSite patch_site(masm_);
1688 patch_site.EmitJumpIfSmi(scratch1, &smi_case); 1691 patch_site.EmitJumpIfSmi(scratch1, &smi_case);
1689 1692
1690 __ bind(&stub_call); 1693 __ bind(&stub_call);
1691 BinaryOpStub stub(op, mode); 1694 BinaryOpStub stub(op, mode);
1692 EmitCallIC(stub.GetCode(), &patch_site, expr->id()); 1695 EmitCallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id());
1696 patch_site.EmitPatchInfo();
1693 __ jmp(&done); 1697 __ jmp(&done);
1694 1698
1695 __ bind(&smi_case); 1699 __ bind(&smi_case);
1696 // Smi case. This code works the same way as the smi-smi case in the type 1700 // Smi case. This code works the same way as the smi-smi case in the type
1697 // recording binary operation stub, see 1701 // recording binary operation stub, see
1698 // BinaryOpStub::GenerateSmiSmiOperation for comments. 1702 // BinaryOpStub::GenerateSmiSmiOperation for comments.
1699 switch (op) { 1703 switch (op) {
1700 case Token::SAR: 1704 case Token::SAR:
1701 __ b(&stub_call); 1705 __ b(&stub_call);
1702 __ GetLeastBitsFromSmi(scratch1, right, 5); 1706 __ GetLeastBitsFromSmi(scratch1, right, 5);
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1763 __ bind(&done); 1767 __ bind(&done);
1764 context()->Plug(r0); 1768 context()->Plug(r0);
1765 } 1769 }
1766 1770
1767 1771
1768 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, 1772 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr,
1769 Token::Value op, 1773 Token::Value op,
1770 OverwriteMode mode) { 1774 OverwriteMode mode) {
1771 __ pop(r1); 1775 __ pop(r1);
1772 BinaryOpStub stub(op, mode); 1776 BinaryOpStub stub(op, mode);
1773 EmitCallIC(stub.GetCode(), NULL, expr->id()); 1777 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
1778 EmitCallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id());
1779 patch_site.EmitPatchInfo();
1774 context()->Plug(r0); 1780 context()->Plug(r0);
1775 } 1781 }
1776 1782
1777 1783
1778 void FullCodeGenerator::EmitAssignment(Expression* expr, int bailout_ast_id) { 1784 void FullCodeGenerator::EmitAssignment(Expression* expr, int bailout_ast_id) {
1779 // Invalid left-hand sides are rewritten to have a 'throw 1785 // Invalid left-hand sides are rewritten to have a 'throw
1780 // ReferenceError' on the left-hand side. 1786 // ReferenceError' on the left-hand side.
1781 if (!expr->IsValidLeftHandSide()) { 1787 if (!expr->IsValidLeftHandSide()) {
1782 VisitForEffect(expr); 1788 VisitForEffect(expr);
1783 return; 1789 return;
(...skipping 2062 matching lines...) Expand 10 before | Expand all | Expand 10 after
3846 __ bind(&stub_call); 3852 __ bind(&stub_call);
3847 // Call stub. Undo operation first. 3853 // Call stub. Undo operation first.
3848 __ sub(r0, r0, Operand(Smi::FromInt(count_value))); 3854 __ sub(r0, r0, Operand(Smi::FromInt(count_value)));
3849 } 3855 }
3850 __ mov(r1, Operand(Smi::FromInt(count_value))); 3856 __ mov(r1, Operand(Smi::FromInt(count_value)));
3851 3857
3852 // Record position before stub call. 3858 // Record position before stub call.
3853 SetSourcePosition(expr->position()); 3859 SetSourcePosition(expr->position());
3854 3860
3855 BinaryOpStub stub(Token::ADD, NO_OVERWRITE); 3861 BinaryOpStub stub(Token::ADD, NO_OVERWRITE);
3856 EmitCallIC(stub.GetCode(), &patch_site, expr->CountId()); 3862 EmitCallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->CountId());
3863 patch_site.EmitPatchInfo();
3857 __ bind(&done); 3864 __ bind(&done);
3858 3865
3859 // Store the value returned in r0. 3866 // Store the value returned in r0.
3860 switch (assign_type) { 3867 switch (assign_type) {
3861 case VARIABLE: 3868 case VARIABLE:
3862 if (expr->is_postfix()) { 3869 if (expr->is_postfix()) {
3863 { EffectContext context(this); 3870 { EffectContext context(this);
3864 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 3871 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
3865 Token::ASSIGN); 3872 Token::ASSIGN);
3866 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3873 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after
4119 __ orr(r2, r0, Operand(r1)); 4126 __ orr(r2, r0, Operand(r1));
4120 patch_site.EmitJumpIfNotSmi(r2, &slow_case); 4127 patch_site.EmitJumpIfNotSmi(r2, &slow_case);
4121 __ cmp(r1, r0); 4128 __ cmp(r1, r0);
4122 Split(cond, if_true, if_false, NULL); 4129 Split(cond, if_true, if_false, NULL);
4123 __ bind(&slow_case); 4130 __ bind(&slow_case);
4124 } 4131 }
4125 4132
4126 // Record position and call the compare IC. 4133 // Record position and call the compare IC.
4127 SetSourcePosition(expr->position()); 4134 SetSourcePosition(expr->position());
4128 Handle<Code> ic = CompareIC::GetUninitialized(op); 4135 Handle<Code> ic = CompareIC::GetUninitialized(op);
4129 EmitCallIC(ic, &patch_site, expr->id()); 4136 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id());
4137 patch_site.EmitPatchInfo();
4130 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); 4138 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
4131 __ cmp(r0, Operand(0)); 4139 __ cmp(r0, Operand(0));
4132 Split(cond, if_true, if_false, fall_through); 4140 Split(cond, if_true, if_false, fall_through);
4133 } 4141 }
4134 } 4142 }
4135 4143
4136 // Convert the result of the comparison into one expected for this 4144 // Convert the result of the comparison into one expected for this
4137 // expression's context. 4145 // expression's context.
4138 context()->Plug(if_true, if_false); 4146 context()->Plug(if_true, if_false);
4139 } 4147 }
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
4185 Register FullCodeGenerator::context_register() { 4193 Register FullCodeGenerator::context_register() {
4186 return cp; 4194 return cp;
4187 } 4195 }
4188 4196
4189 4197
4190 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, 4198 void FullCodeGenerator::EmitCallIC(Handle<Code> ic,
4191 RelocInfo::Mode mode, 4199 RelocInfo::Mode mode,
4192 unsigned ast_id) { 4200 unsigned ast_id) {
4193 ASSERT(mode == RelocInfo::CODE_TARGET || 4201 ASSERT(mode == RelocInfo::CODE_TARGET ||
4194 mode == RelocInfo::CODE_TARGET_CONTEXT); 4202 mode == RelocInfo::CODE_TARGET_CONTEXT);
4195 Counters* counters = isolate()->counters();
4196 switch (ic->kind()) {
4197 case Code::LOAD_IC:
4198 __ IncrementCounter(counters->named_load_full(), 1, r1, r2);
4199 break;
4200 case Code::KEYED_LOAD_IC:
4201 __ IncrementCounter(counters->keyed_load_full(), 1, r1, r2);
4202 break;
4203 case Code::STORE_IC:
4204 __ IncrementCounter(counters->named_store_full(), 1, r1, r2);
4205 break;
4206 case Code::KEYED_STORE_IC:
4207 __ IncrementCounter(counters->keyed_store_full(), 1, r1, r2);
4208 default:
4209 break;
4210 }
4211 if (ast_id == kNoASTId || mode == RelocInfo::CODE_TARGET_CONTEXT) { 4203 if (ast_id == kNoASTId || mode == RelocInfo::CODE_TARGET_CONTEXT) {
4212 __ Call(ic, mode); 4204 __ Call(ic, mode);
4213 } else { 4205 } else {
4214 ASSERT(mode == RelocInfo::CODE_TARGET); 4206 ASSERT(mode == RelocInfo::CODE_TARGET);
4215 mode = RelocInfo::CODE_TARGET_WITH_ID; 4207 __ CallWithAstId(ic, RelocInfo::CODE_TARGET_WITH_ID, ast_id);
4216 __ CallWithAstId(ic, mode, ast_id);
4217 } 4208 }
4218 } 4209 }
4219 4210
4220 4211
4221 void FullCodeGenerator::EmitCallIC(Handle<Code> ic,
4222 JumpPatchSite* patch_site,
4223 unsigned ast_id) {
4224 Counters* counters = isolate()->counters();
4225 switch (ic->kind()) {
4226 case Code::LOAD_IC:
4227 __ IncrementCounter(counters->named_load_full(), 1, r1, r2);
4228 break;
4229 case Code::KEYED_LOAD_IC:
4230 __ IncrementCounter(counters->keyed_load_full(), 1, r1, r2);
4231 break;
4232 case Code::STORE_IC:
4233 __ IncrementCounter(counters->named_store_full(), 1, r1, r2);
4234 break;
4235 case Code::KEYED_STORE_IC:
4236 __ IncrementCounter(counters->keyed_store_full(), 1, r1, r2);
4237 default:
4238 break;
4239 }
4240
4241 if (ast_id == kNoASTId) {
4242 __ Call(ic, RelocInfo::CODE_TARGET);
4243 } else {
4244 __ CallWithAstId(ic, RelocInfo::CODE_TARGET_WITH_ID, ast_id);
4245 }
4246 if (patch_site != NULL && patch_site->is_bound()) {
4247 patch_site->EmitPatchInfo();
4248 } else {
4249 __ nop(); // Signals no inlined code.
4250 }
4251 }
4252
4253
4254 void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) { 4212 void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) {
4255 ASSERT_EQ(POINTER_SIZE_ALIGN(frame_offset), frame_offset); 4213 ASSERT_EQ(POINTER_SIZE_ALIGN(frame_offset), frame_offset);
4256 __ str(value, MemOperand(fp, frame_offset)); 4214 __ str(value, MemOperand(fp, frame_offset));
4257 } 4215 }
4258 4216
4259 4217
4260 void FullCodeGenerator::LoadContextField(Register dst, int context_index) { 4218 void FullCodeGenerator::LoadContextField(Register dst, int context_index) {
4261 __ ldr(dst, ContextOperand(cp, context_index)); 4219 __ ldr(dst, ContextOperand(cp, context_index));
4262 } 4220 }
4263 4221
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
4308 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. 4266 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value.
4309 __ add(pc, r1, Operand(masm_->CodeObject())); 4267 __ add(pc, r1, Operand(masm_->CodeObject()));
4310 } 4268 }
4311 4269
4312 4270
4313 #undef __ 4271 #undef __
4314 4272
4315 } } // namespace v8::internal 4273 } } // namespace v8::internal
4316 4274
4317 #endif // V8_TARGET_ARCH_ARM 4275 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « no previous file | src/full-codegen.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698