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

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

Issue 7212020: MIPS: port Introduce scopes to keep track of catch blocks at compile time. (Closed)
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
« no previous file with comments | « no previous file | no next file » | 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 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
132 // o cp: our context 132 // o cp: our context
133 // o fp: our caller's frame pointer 133 // o fp: our caller's frame pointer
134 // o sp: stack pointer 134 // o sp: stack pointer
135 // o ra: return address 135 // o ra: return address
136 // 136 //
137 // The function builds a JS frame. Please see JavaScriptFrameConstants in 137 // The function builds a JS frame. Please see JavaScriptFrameConstants in
138 // frames-mips.h for its layout. 138 // frames-mips.h for its layout.
139 void FullCodeGenerator::Generate(CompilationInfo* info) { 139 void FullCodeGenerator::Generate(CompilationInfo* info) {
140 ASSERT(info_ == NULL); 140 ASSERT(info_ == NULL);
141 info_ = info; 141 info_ = info;
142 scope_ = info->scope();
142 SetFunctionPosition(function()); 143 SetFunctionPosition(function());
143 Comment cmnt(masm_, "[ function compiled by full code generator"); 144 Comment cmnt(masm_, "[ function compiled by full code generator");
144 145
145 #ifdef DEBUG 146 #ifdef DEBUG
146 if (strlen(FLAG_stop_at) > 0 && 147 if (strlen(FLAG_stop_at) > 0 &&
147 info->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) { 148 info->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) {
148 __ stop("stop-at"); 149 __ stop("stop-at");
149 } 150 }
150 #endif 151 #endif
151 152
152 // Strict mode functions and builtins need to replace the receiver 153 // Strict mode functions and builtins need to replace the receiver
153 // with undefined when called as functions (without an explicit 154 // with undefined when called as functions (without an explicit
154 // receiver object). t1 is zero for method calls and non-zero for 155 // receiver object). t1 is zero for method calls and non-zero for
155 // function calls. 156 // function calls.
156 if (info->is_strict_mode() || info->is_native()) { 157 if (info->is_strict_mode() || info->is_native()) {
157 Label ok; 158 Label ok;
158 __ Branch(&ok, eq, t1, Operand(zero_reg)); 159 __ Branch(&ok, eq, t1, Operand(zero_reg));
159 int receiver_offset = scope()->num_parameters() * kPointerSize; 160 int receiver_offset = info->scope()->num_parameters() * kPointerSize;
160 __ LoadRoot(a2, Heap::kUndefinedValueRootIndex); 161 __ LoadRoot(a2, Heap::kUndefinedValueRootIndex);
161 __ sw(a2, MemOperand(sp, receiver_offset)); 162 __ sw(a2, MemOperand(sp, receiver_offset));
162 __ bind(&ok); 163 __ bind(&ok);
163 } 164 }
164 165
165 int locals_count = scope()->num_stack_slots(); 166 int locals_count = info->scope()->num_stack_slots();
166 167
167 __ Push(ra, fp, cp, a1); 168 __ Push(ra, fp, cp, a1);
168 if (locals_count > 0) { 169 if (locals_count > 0) {
169 // Load undefined value here, so the value is ready for the loop 170 // Load undefined value here, so the value is ready for the loop
170 // below. 171 // below.
171 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); 172 __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
172 } 173 }
173 // Adjust fp to point to caller's fp. 174 // Adjust fp to point to caller's fp.
174 __ Addu(fp, sp, Operand(2 * kPointerSize)); 175 __ Addu(fp, sp, Operand(2 * kPointerSize));
175 176
176 { Comment cmnt(masm_, "[ Allocate locals"); 177 { Comment cmnt(masm_, "[ Allocate locals");
177 for (int i = 0; i < locals_count; i++) { 178 for (int i = 0; i < locals_count; i++) {
178 __ push(at); 179 __ push(at);
179 } 180 }
180 } 181 }
181 182
182 bool function_in_register = true; 183 bool function_in_register = true;
183 184
184 // Possibly allocate a local context. 185 // Possibly allocate a local context.
185 int heap_slots = scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; 186 int heap_slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
186 if (heap_slots > 0) { 187 if (heap_slots > 0) {
187 Comment cmnt(masm_, "[ Allocate local context"); 188 Comment cmnt(masm_, "[ Allocate local context");
188 // Argument to NewContext is the function, which is in a1. 189 // Argument to NewContext is the function, which is in a1.
189 __ push(a1); 190 __ push(a1);
190 if (heap_slots <= FastNewContextStub::kMaximumSlots) { 191 if (heap_slots <= FastNewContextStub::kMaximumSlots) {
191 FastNewContextStub stub(heap_slots); 192 FastNewContextStub stub(heap_slots);
192 __ CallStub(&stub); 193 __ CallStub(&stub);
193 } else { 194 } else {
194 __ CallRuntime(Runtime::kNewFunctionContext, 1); 195 __ CallRuntime(Runtime::kNewFunctionContext, 1);
195 } 196 }
196 function_in_register = false; 197 function_in_register = false;
197 // Context is returned in both v0 and cp. It replaces the context 198 // Context is returned in both v0 and cp. It replaces the context
198 // passed to us. It's saved in the stack and kept live in cp. 199 // passed to us. It's saved in the stack and kept live in cp.
199 __ sw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 200 __ sw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
200 // Copy any necessary parameters into the context. 201 // Copy any necessary parameters into the context.
201 int num_parameters = scope()->num_parameters(); 202 int num_parameters = info->scope()->num_parameters();
202 for (int i = 0; i < num_parameters; i++) { 203 for (int i = 0; i < num_parameters; i++) {
203 Slot* slot = scope()->parameter(i)->AsSlot(); 204 Slot* slot = scope()->parameter(i)->AsSlot();
204 if (slot != NULL && slot->type() == Slot::CONTEXT) { 205 if (slot != NULL && slot->type() == Slot::CONTEXT) {
205 int parameter_offset = StandardFrameConstants::kCallerSPOffset + 206 int parameter_offset = StandardFrameConstants::kCallerSPOffset +
206 (num_parameters - 1 - i) * kPointerSize; 207 (num_parameters - 1 - i) * kPointerSize;
207 // Load parameter from stack. 208 // Load parameter from stack.
208 __ lw(a0, MemOperand(fp, parameter_offset)); 209 __ lw(a0, MemOperand(fp, parameter_offset));
209 // Store it in the context. 210 // Store it in the context.
210 __ li(a1, Operand(Context::SlotOffset(slot->index()))); 211 __ li(a1, Operand(Context::SlotOffset(slot->index())));
211 __ addu(a2, cp, a1); 212 __ addu(a2, cp, a1);
(...skipping 11 matching lines...) Expand all
223 if (arguments != NULL) { 224 if (arguments != NULL) {
224 // Function uses arguments object. 225 // Function uses arguments object.
225 Comment cmnt(masm_, "[ Allocate arguments object"); 226 Comment cmnt(masm_, "[ Allocate arguments object");
226 if (!function_in_register) { 227 if (!function_in_register) {
227 // Load this again, if it's used by the local context below. 228 // Load this again, if it's used by the local context below.
228 __ lw(a3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 229 __ lw(a3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
229 } else { 230 } else {
230 __ mov(a3, a1); 231 __ mov(a3, a1);
231 } 232 }
232 // Receiver is just before the parameters on the caller's stack. 233 // Receiver is just before the parameters on the caller's stack.
233 int offset = scope()->num_parameters() * kPointerSize; 234 int num_parameters = info->scope()->num_parameters();
235 int offset = num_parameters * kPointerSize;
234 __ Addu(a2, fp, 236 __ Addu(a2, fp,
235 Operand(StandardFrameConstants::kCallerSPOffset + offset)); 237 Operand(StandardFrameConstants::kCallerSPOffset + offset));
236 __ li(a1, Operand(Smi::FromInt(scope()->num_parameters()))); 238 __ li(a1, Operand(Smi::FromInt(num_parameters)));
237 __ Push(a3, a2, a1); 239 __ Push(a3, a2, a1);
238 240
239 // Arguments to ArgumentsAccessStub: 241 // Arguments to ArgumentsAccessStub:
240 // function, receiver address, parameter count. 242 // function, receiver address, parameter count.
241 // The stub will rewrite receiever and parameter count if the previous 243 // The stub will rewrite receiever and parameter count if the previous
242 // stack frame was an arguments adapter frame. 244 // stack frame was an arguments adapter frame.
243 ArgumentsAccessStub::Type type; 245 ArgumentsAccessStub::Type type;
244 if (is_strict_mode()) { 246 if (is_strict_mode()) {
245 type = ArgumentsAccessStub::NEW_STRICT; 247 type = ArgumentsAccessStub::NEW_STRICT;
246 } else if (function()->has_duplicate_parameters()) { 248 } else if (function()->has_duplicate_parameters()) {
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
343 #ifdef DEBUG 345 #ifdef DEBUG
344 // Add a label for checking the size of the code used for returning. 346 // Add a label for checking the size of the code used for returning.
345 Label check_exit_codesize; 347 Label check_exit_codesize;
346 masm_->bind(&check_exit_codesize); 348 masm_->bind(&check_exit_codesize);
347 #endif 349 #endif
348 // Make sure that the constant pool is not emitted inside of the return 350 // Make sure that the constant pool is not emitted inside of the return
349 // sequence. 351 // sequence.
350 { Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_); 352 { Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_);
351 // Here we use masm_-> instead of the __ macro to avoid the code coverage 353 // Here we use masm_-> instead of the __ macro to avoid the code coverage
352 // tool from instrumenting as we rely on the code size here. 354 // tool from instrumenting as we rely on the code size here.
353 int32_t sp_delta = (scope()->num_parameters() + 1) * kPointerSize; 355 int32_t sp_delta = (info_->scope()->num_parameters() + 1) * kPointerSize;
354 CodeGenerator::RecordPositions(masm_, function()->end_position() - 1); 356 CodeGenerator::RecordPositions(masm_, function()->end_position() - 1);
355 __ RecordJSReturn(); 357 __ RecordJSReturn();
356 masm_->mov(sp, fp); 358 masm_->mov(sp, fp);
357 masm_->MultiPop(static_cast<RegList>(fp.bit() | ra.bit())); 359 masm_->MultiPop(static_cast<RegList>(fp.bit() | ra.bit()));
358 masm_->Addu(sp, sp, Operand(sp_delta)); 360 masm_->Addu(sp, sp, Operand(sp_delta));
359 masm_->Jump(ra); 361 masm_->Jump(ra);
360 } 362 }
361 363
362 #ifdef DEBUG 364 #ifdef DEBUG
363 // Check that the size of the code used for returning is large enough 365 // Check that the size of the code used for returning is large enough
(...skipping 1768 matching lines...) Expand 10 before | Expand all | Expand 10 after
2132 int arg_count) { 2134 int arg_count) {
2133 // Push copy of the first argument or undefined if it doesn't exist. 2135 // Push copy of the first argument or undefined if it doesn't exist.
2134 if (arg_count > 0) { 2136 if (arg_count > 0) {
2135 __ lw(a1, MemOperand(sp, arg_count * kPointerSize)); 2137 __ lw(a1, MemOperand(sp, arg_count * kPointerSize));
2136 } else { 2138 } else {
2137 __ LoadRoot(a1, Heap::kUndefinedValueRootIndex); 2139 __ LoadRoot(a1, Heap::kUndefinedValueRootIndex);
2138 } 2140 }
2139 __ push(a1); 2141 __ push(a1);
2140 2142
2141 // Push the receiver of the enclosing function and do runtime call. 2143 // Push the receiver of the enclosing function and do runtime call.
2142 __ lw(a1, MemOperand(fp, (2 + scope()->num_parameters()) * kPointerSize)); 2144 int receiver_offset = 2 + info_->scope()->num_parameters();
2145 __ lw(a1, MemOperand(fp, receiver_offset * kPointerSize));
2143 __ push(a1); 2146 __ push(a1);
2144 // Push the strict mode flag. 2147 // Push the strict mode flag.
2145 __ li(a1, Operand(Smi::FromInt(strict_mode_flag()))); 2148 __ li(a1, Operand(Smi::FromInt(strict_mode_flag())));
2146 __ push(a1); 2149 __ push(a1);
2147 2150
2148 __ CallRuntime(flag == SKIP_CONTEXT_LOOKUP 2151 __ CallRuntime(flag == SKIP_CONTEXT_LOOKUP
2149 ? Runtime::kResolvePossiblyDirectEvalNoLookup 2152 ? Runtime::kResolvePossiblyDirectEvalNoLookup
2150 : Runtime::kResolvePossiblyDirectEval, 4); 2153 : Runtime::kResolvePossiblyDirectEval, 4);
2151 } 2154 }
2152 2155
(...skipping 525 matching lines...) Expand 10 before | Expand all | Expand 10 after
2678 } 2681 }
2679 2682
2680 2683
2681 void FullCodeGenerator::EmitArguments(ZoneList<Expression*>* args) { 2684 void FullCodeGenerator::EmitArguments(ZoneList<Expression*>* args) {
2682 ASSERT(args->length() == 1); 2685 ASSERT(args->length() == 1);
2683 2686
2684 // ArgumentsAccessStub expects the key in a1 and the formal 2687 // ArgumentsAccessStub expects the key in a1 and the formal
2685 // parameter count in a0. 2688 // parameter count in a0.
2686 VisitForAccumulatorValue(args->at(0)); 2689 VisitForAccumulatorValue(args->at(0));
2687 __ mov(a1, v0); 2690 __ mov(a1, v0);
2688 __ li(a0, Operand(Smi::FromInt(scope()->num_parameters()))); 2691 __ li(a0, Operand(Smi::FromInt(info_->scope()->num_parameters())));
2689 ArgumentsAccessStub stub(ArgumentsAccessStub::READ_ELEMENT); 2692 ArgumentsAccessStub stub(ArgumentsAccessStub::READ_ELEMENT);
2690 __ CallStub(&stub); 2693 __ CallStub(&stub);
2691 context()->Plug(v0); 2694 context()->Plug(v0);
2692 } 2695 }
2693 2696
2694 2697
2695 void FullCodeGenerator::EmitArgumentsLength(ZoneList<Expression*>* args) { 2698 void FullCodeGenerator::EmitArgumentsLength(ZoneList<Expression*>* args) {
2696 ASSERT(args->length() == 0); 2699 ASSERT(args->length() == 0);
2697 2700
2698 Label exit; 2701 Label exit;
2699 // Get the number of formal parameters. 2702 // Get the number of formal parameters.
2700 __ li(v0, Operand(Smi::FromInt(scope()->num_parameters()))); 2703 __ li(v0, Operand(Smi::FromInt(info_->scope()->num_parameters())));
2701 2704
2702 // Check if the calling frame is an arguments adaptor frame. 2705 // Check if the calling frame is an arguments adaptor frame.
2703 __ lw(a2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); 2706 __ lw(a2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
2704 __ lw(a3, MemOperand(a2, StandardFrameConstants::kContextOffset)); 2707 __ lw(a3, MemOperand(a2, StandardFrameConstants::kContextOffset));
2705 __ Branch(&exit, ne, a3, 2708 __ Branch(&exit, ne, a3,
2706 Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); 2709 Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
2707 2710
2708 // Arguments adaptor case: Read the arguments length from the 2711 // Arguments adaptor case: Read the arguments length from the
2709 // adaptor frame. 2712 // adaptor frame.
2710 __ lw(v0, MemOperand(a2, ArgumentsAdaptorFrameConstants::kLengthOffset)); 2713 __ lw(v0, MemOperand(a2, ArgumentsAdaptorFrameConstants::kLengthOffset));
(...skipping 1520 matching lines...) Expand 10 before | Expand all | Expand 10 after
4231 // as their closure, not the anonymous closure containing the global 4234 // as their closure, not the anonymous closure containing the global
4232 // code. Pass a smi sentinel and let the runtime look up the empty 4235 // code. Pass a smi sentinel and let the runtime look up the empty
4233 // function. 4236 // function.
4234 __ li(at, Operand(Smi::FromInt(0))); 4237 __ li(at, Operand(Smi::FromInt(0)));
4235 } else if (scope()->is_eval_scope()) { 4238 } else if (scope()->is_eval_scope()) {
4236 // Contexts created by a call to eval have the same closure as the 4239 // Contexts created by a call to eval have the same closure as the
4237 // context calling eval, not the anonymous closure containing the eval 4240 // context calling eval, not the anonymous closure containing the eval
4238 // code. Fetch it from the context. 4241 // code. Fetch it from the context.
4239 __ lw(at, ContextOperand(cp, Context::CLOSURE_INDEX)); 4242 __ lw(at, ContextOperand(cp, Context::CLOSURE_INDEX));
4240 } else { 4243 } else {
4241 ASSERT(scope()->is_function_scope()); 4244 ASSERT(scope()->is_function_scope() || scope()->is_catch_scope());
4242 __ lw(at, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 4245 __ lw(at, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
4243 } 4246 }
4244 __ push(at); 4247 __ push(at);
4245 } 4248 }
4246 4249
4247 4250
4248 // ---------------------------------------------------------------------------- 4251 // ----------------------------------------------------------------------------
4249 // Non-local control flow support. 4252 // Non-local control flow support.
4250 4253
4251 void FullCodeGenerator::EnterFinallyBlock() { 4254 void FullCodeGenerator::EnterFinallyBlock() {
(...skipping 20 matching lines...) Expand all
4272 __ Addu(at, a1, Operand(masm_->CodeObject())); 4275 __ Addu(at, a1, Operand(masm_->CodeObject()));
4273 __ Jump(at); 4276 __ Jump(at);
4274 } 4277 }
4275 4278
4276 4279
4277 #undef __ 4280 #undef __
4278 4281
4279 } } // namespace v8::internal 4282 } } // namespace v8::internal
4280 4283
4281 #endif // V8_TARGET_ARCH_MIPS 4284 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698