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

Side by Side Diff: src/mips/full-codegen-mips.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 | « src/ia32/full-codegen-ia32.cc ('k') | src/v8-counters.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 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
94 void EmitJumpIfSmi(Register reg, Label* target) { 94 void EmitJumpIfSmi(Register reg, Label* target) {
95 Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_); 95 Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_);
96 ASSERT(!patch_site_.is_bound() && !info_emitted_); 96 ASSERT(!patch_site_.is_bound() && !info_emitted_);
97 __ bind(&patch_site_); 97 __ bind(&patch_site_);
98 __ andi(at, reg, 0); 98 __ andi(at, reg, 0);
99 // Never taken before patched. 99 // Never taken before patched.
100 __ Branch(target, ne, at, Operand(zero_reg)); 100 __ Branch(target, ne, at, Operand(zero_reg));
101 } 101 }
102 102
103 void EmitPatchInfo() { 103 void EmitPatchInfo() {
104 int delta_to_patch_site = masm_->InstructionsGeneratedSince(&patch_site_); 104 if (patch_site_.is_bound()) {
105 Register reg = Register::from_code(delta_to_patch_site / kImm16Mask); 105 int delta_to_patch_site = masm_->InstructionsGeneratedSince(&patch_site_);
106 __ andi(at, reg, delta_to_patch_site % kImm16Mask); 106 Register reg = Register::from_code(delta_to_patch_site / kImm16Mask);
107 __ andi(at, reg, delta_to_patch_site % kImm16Mask);
107 #ifdef DEBUG 108 #ifdef DEBUG
108 info_emitted_ = true; 109 info_emitted_ = true;
109 #endif 110 #endif
111 } else {
112 __ nop(); // Signals no inlined code.
113 }
110 } 114 }
111 115
112 bool is_bound() const { return patch_site_.is_bound(); }
113
114 private: 116 private:
115 MacroAssembler* masm_; 117 MacroAssembler* masm_;
116 Label patch_site_; 118 Label patch_site_;
117 #ifdef DEBUG 119 #ifdef DEBUG
118 bool info_emitted_; 120 bool info_emitted_;
119 #endif 121 #endif
120 }; 122 };
121 123
122 124
123 // Generate code for a JS function. On entry to the function the receiver 125 // Generate code for a JS function. On entry to the function the receiver
(...skipping 734 matching lines...) Expand 10 before | Expand all | Expand 10 after
858 __ Branch(&next_test, ne, a1, Operand(a0)); 860 __ Branch(&next_test, ne, a1, Operand(a0));
859 __ Drop(1); // Switch value is no longer needed. 861 __ Drop(1); // Switch value is no longer needed.
860 __ Branch(clause->body_target()); 862 __ Branch(clause->body_target());
861 863
862 __ bind(&slow_case); 864 __ bind(&slow_case);
863 } 865 }
864 866
865 // Record position before stub call for type feedback. 867 // Record position before stub call for type feedback.
866 SetSourcePosition(clause->position()); 868 SetSourcePosition(clause->position());
867 Handle<Code> ic = CompareIC::GetUninitialized(Token::EQ_STRICT); 869 Handle<Code> ic = CompareIC::GetUninitialized(Token::EQ_STRICT);
868 EmitCallIC(ic, &patch_site, clause->CompareId()); 870 EmitCallIC(ic, RelocInfo::CODE_TARGET, clause->CompareId());
871 patch_site.EmitPatchInfo();
869 872
870 __ Branch(&next_test, ne, v0, Operand(zero_reg)); 873 __ Branch(&next_test, ne, v0, Operand(zero_reg));
871 __ Drop(1); // Switch value is no longer needed. 874 __ Drop(1); // Switch value is no longer needed.
872 __ Branch(clause->body_target()); 875 __ Branch(clause->body_target());
873 } 876 }
874 877
875 // Discard the test value and jump to the default if present, otherwise to 878 // Discard the test value and jump to the default if present, otherwise to
876 // the end of the statement. 879 // the end of the statement.
877 __ bind(&next_test); 880 __ bind(&next_test);
878 __ Drop(1); // Switch value is no longer needed. 881 __ Drop(1); // Switch value is no longer needed.
(...skipping 807 matching lines...) Expand 10 before | Expand all | Expand 10 after
1686 __ mov(a0, result_register()); 1689 __ mov(a0, result_register());
1687 1690
1688 // Perform combined smi check on both operands. 1691 // Perform combined smi check on both operands.
1689 __ Or(scratch1, left, Operand(right)); 1692 __ Or(scratch1, left, Operand(right));
1690 STATIC_ASSERT(kSmiTag == 0); 1693 STATIC_ASSERT(kSmiTag == 0);
1691 JumpPatchSite patch_site(masm_); 1694 JumpPatchSite patch_site(masm_);
1692 patch_site.EmitJumpIfSmi(scratch1, &smi_case); 1695 patch_site.EmitJumpIfSmi(scratch1, &smi_case);
1693 1696
1694 __ bind(&stub_call); 1697 __ bind(&stub_call);
1695 BinaryOpStub stub(op, mode); 1698 BinaryOpStub stub(op, mode);
1696 EmitCallIC(stub.GetCode(), &patch_site, expr->id()); 1699 EmitCallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id());
1700 patch_site.EmitPatchInfo();
1697 __ jmp(&done); 1701 __ jmp(&done);
1698 1702
1699 __ bind(&smi_case); 1703 __ bind(&smi_case);
1700 // Smi case. This code works the same way as the smi-smi case in the type 1704 // Smi case. This code works the same way as the smi-smi case in the type
1701 // recording binary operation stub, see 1705 // recording binary operation stub, see
1702 // BinaryOpStub::GenerateSmiSmiOperation for comments. 1706 // BinaryOpStub::GenerateSmiSmiOperation for comments.
1703 switch (op) { 1707 switch (op) {
1704 case Token::SAR: 1708 case Token::SAR:
1705 __ Branch(&stub_call); 1709 __ Branch(&stub_call);
1706 __ GetLeastBitsFromSmi(scratch1, right, 5); 1710 __ GetLeastBitsFromSmi(scratch1, right, 5);
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1767 context()->Plug(v0); 1771 context()->Plug(v0);
1768 } 1772 }
1769 1773
1770 1774
1771 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, 1775 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr,
1772 Token::Value op, 1776 Token::Value op,
1773 OverwriteMode mode) { 1777 OverwriteMode mode) {
1774 __ mov(a0, result_register()); 1778 __ mov(a0, result_register());
1775 __ pop(a1); 1779 __ pop(a1);
1776 BinaryOpStub stub(op, mode); 1780 BinaryOpStub stub(op, mode);
1777 EmitCallIC(stub.GetCode(), NULL, expr->id()); 1781 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
1782 EmitCallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id());
1783 patch_site.EmitPatchInfo();
1778 context()->Plug(v0); 1784 context()->Plug(v0);
1779 } 1785 }
1780 1786
1781 1787
1782 void FullCodeGenerator::EmitAssignment(Expression* expr, int bailout_ast_id) { 1788 void FullCodeGenerator::EmitAssignment(Expression* expr, int bailout_ast_id) {
1783 // Invalid left-hand sides are rewritten to have a 'throw 1789 // Invalid left-hand sides are rewritten to have a 'throw
1784 // ReferenceError' on the left-hand side. 1790 // ReferenceError' on the left-hand side.
1785 if (!expr->IsValidLeftHandSide()) { 1791 if (!expr->IsValidLeftHandSide()) {
1786 VisitForEffect(expr); 1792 VisitForEffect(expr);
1787 return; 1793 return;
(...skipping 2087 matching lines...) Expand 10 before | Expand all | Expand 10 after
3875 // We could eliminate this smi check if we split the code at 3881 // We could eliminate this smi check if we split the code at
3876 // the first smi check before calling ToNumber. 3882 // the first smi check before calling ToNumber.
3877 patch_site.EmitJumpIfSmi(v0, &done); 3883 patch_site.EmitJumpIfSmi(v0, &done);
3878 __ bind(&stub_call); 3884 __ bind(&stub_call);
3879 } 3885 }
3880 3886
3881 // Record position before stub call. 3887 // Record position before stub call.
3882 SetSourcePosition(expr->position()); 3888 SetSourcePosition(expr->position());
3883 3889
3884 BinaryOpStub stub(Token::ADD, NO_OVERWRITE); 3890 BinaryOpStub stub(Token::ADD, NO_OVERWRITE);
3885 EmitCallIC(stub.GetCode(), &patch_site, expr->CountId()); 3891 EmitCallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->CountId());
3892 patch_site.EmitPatchInfo();
3886 __ bind(&done); 3893 __ bind(&done);
3887 3894
3888 // Store the value returned in v0. 3895 // Store the value returned in v0.
3889 switch (assign_type) { 3896 switch (assign_type) {
3890 case VARIABLE: 3897 case VARIABLE:
3891 if (expr->is_postfix()) { 3898 if (expr->is_postfix()) {
3892 { EffectContext context(this); 3899 { EffectContext context(this);
3893 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 3900 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
3894 Token::ASSIGN); 3901 Token::ASSIGN);
3895 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3902 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after
4146 if (inline_smi_code) { 4153 if (inline_smi_code) {
4147 Label slow_case; 4154 Label slow_case;
4148 __ Or(a2, a0, Operand(a1)); 4155 __ Or(a2, a0, Operand(a1));
4149 patch_site.EmitJumpIfNotSmi(a2, &slow_case); 4156 patch_site.EmitJumpIfNotSmi(a2, &slow_case);
4150 Split(cc, a1, Operand(a0), if_true, if_false, NULL); 4157 Split(cc, a1, Operand(a0), if_true, if_false, NULL);
4151 __ bind(&slow_case); 4158 __ bind(&slow_case);
4152 } 4159 }
4153 // Record position and call the compare IC. 4160 // Record position and call the compare IC.
4154 SetSourcePosition(expr->position()); 4161 SetSourcePosition(expr->position());
4155 Handle<Code> ic = CompareIC::GetUninitialized(op); 4162 Handle<Code> ic = CompareIC::GetUninitialized(op);
4156 EmitCallIC(ic, &patch_site, expr->id()); 4163 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id());
4164 patch_site.EmitPatchInfo();
4157 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); 4165 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
4158 Split(cc, v0, Operand(zero_reg), if_true, if_false, fall_through); 4166 Split(cc, v0, Operand(zero_reg), if_true, if_false, fall_through);
4159 } 4167 }
4160 } 4168 }
4161 4169
4162 // Convert the result of the comparison into one expected for this 4170 // Convert the result of the comparison into one expected for this
4163 // expression's context. 4171 // expression's context.
4164 context()->Plug(if_true, if_false); 4172 context()->Plug(if_true, if_false);
4165 } 4173 }
4166 4174
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
4210 Register FullCodeGenerator::context_register() { 4218 Register FullCodeGenerator::context_register() {
4211 return cp; 4219 return cp;
4212 } 4220 }
4213 4221
4214 4222
4215 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, 4223 void FullCodeGenerator::EmitCallIC(Handle<Code> ic,
4216 RelocInfo::Mode mode, 4224 RelocInfo::Mode mode,
4217 unsigned ast_id) { 4225 unsigned ast_id) {
4218 ASSERT(mode == RelocInfo::CODE_TARGET || 4226 ASSERT(mode == RelocInfo::CODE_TARGET ||
4219 mode == RelocInfo::CODE_TARGET_CONTEXT); 4227 mode == RelocInfo::CODE_TARGET_CONTEXT);
4220 Counters* counters = isolate()->counters();
4221 switch (ic->kind()) {
4222 case Code::LOAD_IC:
4223 __ IncrementCounter(counters->named_load_full(), 1, a1, a2);
4224 break;
4225 case Code::KEYED_LOAD_IC:
4226 __ IncrementCounter(counters->keyed_load_full(), 1, a1, a2);
4227 break;
4228 case Code::STORE_IC:
4229 __ IncrementCounter(counters->named_store_full(), 1, a1, a2);
4230 break;
4231 case Code::KEYED_STORE_IC:
4232 __ IncrementCounter(counters->keyed_store_full(), 1, a1, a2);
4233 default:
4234 break;
4235 }
4236 if (ast_id == kNoASTId || mode == RelocInfo::CODE_TARGET_CONTEXT) { 4228 if (ast_id == kNoASTId || mode == RelocInfo::CODE_TARGET_CONTEXT) {
4237 __ Call(ic, mode); 4229 __ Call(ic, mode);
4238 } else { 4230 } else {
4239 ASSERT(mode == RelocInfo::CODE_TARGET); 4231 ASSERT(mode == RelocInfo::CODE_TARGET);
4240 mode = RelocInfo::CODE_TARGET_WITH_ID; 4232 __ CallWithAstId(ic, RelocInfo::CODE_TARGET_WITH_ID, ast_id);
4241 __ CallWithAstId(ic, mode, ast_id);
4242 } 4233 }
4243 } 4234 }
4244 4235
4245 4236
4246 void FullCodeGenerator::EmitCallIC(Handle<Code> ic,
4247 JumpPatchSite* patch_site,
4248 unsigned ast_id) {
4249 Counters* counters = isolate()->counters();
4250 switch (ic->kind()) {
4251 case Code::LOAD_IC:
4252 __ IncrementCounter(counters->named_load_full(), 1, a1, a2);
4253 break;
4254 case Code::KEYED_LOAD_IC:
4255 __ IncrementCounter(counters->keyed_load_full(), 1, a1, a2);
4256 break;
4257 case Code::STORE_IC:
4258 __ IncrementCounter(counters->named_store_full(), 1, a1, a2);
4259 break;
4260 case Code::KEYED_STORE_IC:
4261 __ IncrementCounter(counters->keyed_store_full(), 1, a1, a2);
4262 default:
4263 break;
4264 }
4265
4266 if (ast_id == kNoASTId) {
4267 __ Call(ic, RelocInfo::CODE_TARGET);
4268 } else {
4269 __ CallWithAstId(ic, RelocInfo::CODE_TARGET_WITH_ID, ast_id);
4270 }
4271 if (patch_site != NULL && patch_site->is_bound()) {
4272 patch_site->EmitPatchInfo();
4273 } else {
4274 __ nop(); // Signals no inlined code.
4275 }
4276 }
4277
4278
4279 void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) { 4237 void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) {
4280 ASSERT_EQ(POINTER_SIZE_ALIGN(frame_offset), frame_offset); 4238 ASSERT_EQ(POINTER_SIZE_ALIGN(frame_offset), frame_offset);
4281 __ sw(value, MemOperand(fp, frame_offset)); 4239 __ sw(value, MemOperand(fp, frame_offset));
4282 } 4240 }
4283 4241
4284 4242
4285 void FullCodeGenerator::LoadContextField(Register dst, int context_index) { 4243 void FullCodeGenerator::LoadContextField(Register dst, int context_index) {
4286 __ lw(dst, ContextOperand(cp, context_index)); 4244 __ lw(dst, ContextOperand(cp, context_index));
4287 } 4245 }
4288 4246
(...skipping 25 matching lines...) Expand all
4314 __ Addu(at, a1, Operand(masm_->CodeObject())); 4272 __ Addu(at, a1, Operand(masm_->CodeObject()));
4315 __ Jump(at); 4273 __ Jump(at);
4316 } 4274 }
4317 4275
4318 4276
4319 #undef __ 4277 #undef __
4320 4278
4321 } } // namespace v8::internal 4279 } } // namespace v8::internal
4322 4280
4323 #endif // V8_TARGET_ARCH_MIPS 4281 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « src/ia32/full-codegen-ia32.cc ('k') | src/v8-counters.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698