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

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

Issue 7280012: Introduce scopes to keep track of catch blocks at compile time. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Update to HEAD. 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/ast.h » ('j') | src/full-codegen.cc » ('J')
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 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
124 // o cp: our context 124 // o cp: our context
125 // o fp: our caller's frame pointer 125 // o fp: our caller's frame pointer
126 // o sp: stack pointer 126 // o sp: stack pointer
127 // o lr: return address 127 // o lr: return address
128 // 128 //
129 // The function builds a JS frame. Please see JavaScriptFrameConstants in 129 // The function builds a JS frame. Please see JavaScriptFrameConstants in
130 // frames-arm.h for its layout. 130 // frames-arm.h for its layout.
131 void FullCodeGenerator::Generate(CompilationInfo* info) { 131 void FullCodeGenerator::Generate(CompilationInfo* info) {
132 ASSERT(info_ == NULL); 132 ASSERT(info_ == NULL);
133 info_ = info; 133 info_ = info;
134 scope_ = info->scope();
134 SetFunctionPosition(function()); 135 SetFunctionPosition(function());
135 Comment cmnt(masm_, "[ function compiled by full code generator"); 136 Comment cmnt(masm_, "[ function compiled by full code generator");
136 137
137 #ifdef DEBUG 138 #ifdef DEBUG
138 if (strlen(FLAG_stop_at) > 0 && 139 if (strlen(FLAG_stop_at) > 0 &&
139 info->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) { 140 info->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) {
140 __ stop("stop-at"); 141 __ stop("stop-at");
141 } 142 }
142 #endif 143 #endif
143 144
144 // Strict mode functions and builtins need to replace the receiver 145 // Strict mode functions and builtins need to replace the receiver
145 // with undefined when called as functions (without an explicit 146 // with undefined when called as functions (without an explicit
146 // receiver object). r5 is zero for method calls and non-zero for 147 // receiver object). r5 is zero for method calls and non-zero for
147 // function calls. 148 // function calls.
148 if (info->is_strict_mode() || info->is_native()) { 149 if (info->is_strict_mode() || info->is_native()) {
149 Label ok; 150 Label ok;
150 __ cmp(r5, Operand(0)); 151 __ cmp(r5, Operand(0));
151 __ b(eq, &ok); 152 __ b(eq, &ok);
152 int receiver_offset = scope()->num_parameters() * kPointerSize; 153 int receiver_offset = info->scope()->num_parameters() * kPointerSize;
Mads Ager (chromium) 2011/06/30 12:08:32 I'm getting a little confused here. You don't need
Kevin Millikin (Chromium) 2011/06/30 12:30:06 I'm being overly defensive. We are definitely not
153 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex); 154 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex);
154 __ str(r2, MemOperand(sp, receiver_offset)); 155 __ str(r2, MemOperand(sp, receiver_offset));
155 __ bind(&ok); 156 __ bind(&ok);
156 } 157 }
157 158
158 int locals_count = scope()->num_stack_slots(); 159 int locals_count = info->scope()->num_stack_slots();
159 160
160 __ Push(lr, fp, cp, r1); 161 __ Push(lr, fp, cp, r1);
161 if (locals_count > 0) { 162 if (locals_count > 0) {
162 // Load undefined value here, so the value is ready for the loop 163 // Load undefined value here, so the value is ready for the loop
163 // below. 164 // below.
164 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); 165 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
165 } 166 }
166 // Adjust fp to point to caller's fp. 167 // Adjust fp to point to caller's fp.
167 __ add(fp, sp, Operand(2 * kPointerSize)); 168 __ add(fp, sp, Operand(2 * kPointerSize));
168 169
169 { Comment cmnt(masm_, "[ Allocate locals"); 170 { Comment cmnt(masm_, "[ Allocate locals");
170 for (int i = 0; i < locals_count; i++) { 171 for (int i = 0; i < locals_count; i++) {
171 __ push(ip); 172 __ push(ip);
172 } 173 }
173 } 174 }
174 175
175 bool function_in_register = true; 176 bool function_in_register = true;
176 177
177 // Possibly allocate a local context. 178 // Possibly allocate a local context.
178 int heap_slots = scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; 179 int heap_slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
179 if (heap_slots > 0) { 180 if (heap_slots > 0) {
180 Comment cmnt(masm_, "[ Allocate local context"); 181 Comment cmnt(masm_, "[ Allocate local context");
181 // Argument to NewContext is the function, which is in r1. 182 // Argument to NewContext is the function, which is in r1.
182 __ push(r1); 183 __ push(r1);
183 if (heap_slots <= FastNewContextStub::kMaximumSlots) { 184 if (heap_slots <= FastNewContextStub::kMaximumSlots) {
184 FastNewContextStub stub(heap_slots); 185 FastNewContextStub stub(heap_slots);
185 __ CallStub(&stub); 186 __ CallStub(&stub);
186 } else { 187 } else {
187 __ CallRuntime(Runtime::kNewFunctionContext, 1); 188 __ CallRuntime(Runtime::kNewFunctionContext, 1);
188 } 189 }
189 function_in_register = false; 190 function_in_register = false;
190 // Context is returned in both r0 and cp. It replaces the context 191 // Context is returned in both r0 and cp. It replaces the context
191 // passed to us. It's saved in the stack and kept live in cp. 192 // passed to us. It's saved in the stack and kept live in cp.
192 __ str(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 193 __ str(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
193 // Copy any necessary parameters into the context. 194 // Copy any necessary parameters into the context.
194 int num_parameters = scope()->num_parameters(); 195 int num_parameters = info->scope()->num_parameters();
195 for (int i = 0; i < num_parameters; i++) { 196 for (int i = 0; i < num_parameters; i++) {
196 Slot* slot = scope()->parameter(i)->AsSlot(); 197 Slot* slot = scope()->parameter(i)->AsSlot();
197 if (slot != NULL && slot->type() == Slot::CONTEXT) { 198 if (slot != NULL && slot->type() == Slot::CONTEXT) {
198 int parameter_offset = StandardFrameConstants::kCallerSPOffset + 199 int parameter_offset = StandardFrameConstants::kCallerSPOffset +
199 (num_parameters - 1 - i) * kPointerSize; 200 (num_parameters - 1 - i) * kPointerSize;
200 // Load parameter from stack. 201 // Load parameter from stack.
201 __ ldr(r0, MemOperand(fp, parameter_offset)); 202 __ ldr(r0, MemOperand(fp, parameter_offset));
202 // Store it in the context. 203 // Store it in the context.
203 __ mov(r1, Operand(Context::SlotOffset(slot->index()))); 204 __ mov(r1, Operand(Context::SlotOffset(slot->index())));
204 __ str(r0, MemOperand(cp, r1)); 205 __ str(r0, MemOperand(cp, r1));
(...skipping 10 matching lines...) Expand all
215 if (arguments != NULL) { 216 if (arguments != NULL) {
216 // Function uses arguments object. 217 // Function uses arguments object.
217 Comment cmnt(masm_, "[ Allocate arguments object"); 218 Comment cmnt(masm_, "[ Allocate arguments object");
218 if (!function_in_register) { 219 if (!function_in_register) {
219 // Load this again, if it's used by the local context below. 220 // Load this again, if it's used by the local context below.
220 __ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 221 __ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
221 } else { 222 } else {
222 __ mov(r3, r1); 223 __ mov(r3, r1);
223 } 224 }
224 // Receiver is just before the parameters on the caller's stack. 225 // Receiver is just before the parameters on the caller's stack.
225 int offset = scope()->num_parameters() * kPointerSize; 226 int num_parameters = info->scope()->num_parameters();
227 int offset = num_parameters * kPointerSize;
226 __ add(r2, fp, 228 __ add(r2, fp,
227 Operand(StandardFrameConstants::kCallerSPOffset + offset)); 229 Operand(StandardFrameConstants::kCallerSPOffset + offset));
228 __ mov(r1, Operand(Smi::FromInt(scope()->num_parameters()))); 230 __ mov(r1, Operand(Smi::FromInt(num_parameters)));
229 __ Push(r3, r2, r1); 231 __ Push(r3, r2, r1);
230 232
231 // Arguments to ArgumentsAccessStub: 233 // Arguments to ArgumentsAccessStub:
232 // function, receiver address, parameter count. 234 // function, receiver address, parameter count.
233 // The stub will rewrite receiever and parameter count if the previous 235 // The stub will rewrite receiever and parameter count if the previous
234 // stack frame was an arguments adapter frame. 236 // stack frame was an arguments adapter frame.
235 ArgumentsAccessStub::Type type; 237 ArgumentsAccessStub::Type type;
236 if (is_strict_mode()) { 238 if (is_strict_mode()) {
237 type = ArgumentsAccessStub::NEW_STRICT; 239 type = ArgumentsAccessStub::NEW_STRICT;
238 } else if (function()->has_duplicate_parameters()) { 240 } else if (function()->has_duplicate_parameters()) {
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
340 #ifdef DEBUG 342 #ifdef DEBUG
341 // Add a label for checking the size of the code used for returning. 343 // Add a label for checking the size of the code used for returning.
342 Label check_exit_codesize; 344 Label check_exit_codesize;
343 masm_->bind(&check_exit_codesize); 345 masm_->bind(&check_exit_codesize);
344 #endif 346 #endif
345 // Make sure that the constant pool is not emitted inside of the return 347 // Make sure that the constant pool is not emitted inside of the return
346 // sequence. 348 // sequence.
347 { Assembler::BlockConstPoolScope block_const_pool(masm_); 349 { Assembler::BlockConstPoolScope block_const_pool(masm_);
348 // Here we use masm_-> instead of the __ macro to avoid the code coverage 350 // Here we use masm_-> instead of the __ macro to avoid the code coverage
349 // tool from instrumenting as we rely on the code size here. 351 // tool from instrumenting as we rely on the code size here.
350 int32_t sp_delta = (scope()->num_parameters() + 1) * kPointerSize; 352 int32_t sp_delta = (info_->scope()->num_parameters() + 1) * kPointerSize;
351 CodeGenerator::RecordPositions(masm_, function()->end_position() - 1); 353 CodeGenerator::RecordPositions(masm_, function()->end_position() - 1);
352 __ RecordJSReturn(); 354 __ RecordJSReturn();
353 masm_->mov(sp, fp); 355 masm_->mov(sp, fp);
354 masm_->ldm(ia_w, sp, fp.bit() | lr.bit()); 356 masm_->ldm(ia_w, sp, fp.bit() | lr.bit());
355 masm_->add(sp, sp, Operand(sp_delta)); 357 masm_->add(sp, sp, Operand(sp_delta));
356 masm_->Jump(lr); 358 masm_->Jump(lr);
357 } 359 }
358 360
359 #ifdef DEBUG 361 #ifdef DEBUG
360 // Check that the size of the code used for returning is large enough 362 // Check that the size of the code used for returning is large enough
(...skipping 1755 matching lines...) Expand 10 before | Expand all | Expand 10 after
2116 int arg_count) { 2118 int arg_count) {
2117 // Push copy of the first argument or undefined if it doesn't exist. 2119 // Push copy of the first argument or undefined if it doesn't exist.
2118 if (arg_count > 0) { 2120 if (arg_count > 0) {
2119 __ ldr(r1, MemOperand(sp, arg_count * kPointerSize)); 2121 __ ldr(r1, MemOperand(sp, arg_count * kPointerSize));
2120 } else { 2122 } else {
2121 __ LoadRoot(r1, Heap::kUndefinedValueRootIndex); 2123 __ LoadRoot(r1, Heap::kUndefinedValueRootIndex);
2122 } 2124 }
2123 __ push(r1); 2125 __ push(r1);
2124 2126
2125 // Push the receiver of the enclosing function and do runtime call. 2127 // Push the receiver of the enclosing function and do runtime call.
2126 __ ldr(r1, MemOperand(fp, (2 + scope()->num_parameters()) * kPointerSize)); 2128 int receiver_offset = 2 + info_->scope()->num_parameters();
2129 __ ldr(r1, MemOperand(fp, receiver_offset * kPointerSize));
2127 __ push(r1); 2130 __ push(r1);
2128 // Push the strict mode flag. 2131 // Push the strict mode flag.
2129 __ mov(r1, Operand(Smi::FromInt(strict_mode_flag()))); 2132 __ mov(r1, Operand(Smi::FromInt(strict_mode_flag())));
2130 __ push(r1); 2133 __ push(r1);
2131 2134
2132 __ CallRuntime(flag == SKIP_CONTEXT_LOOKUP 2135 __ CallRuntime(flag == SKIP_CONTEXT_LOOKUP
2133 ? Runtime::kResolvePossiblyDirectEvalNoLookup 2136 ? Runtime::kResolvePossiblyDirectEvalNoLookup
2134 : Runtime::kResolvePossiblyDirectEval, 4); 2137 : Runtime::kResolvePossiblyDirectEval, 4);
2135 } 2138 }
2136 2139
(...skipping 531 matching lines...) Expand 10 before | Expand all | Expand 10 after
2668 } 2671 }
2669 2672
2670 2673
2671 void FullCodeGenerator::EmitArguments(ZoneList<Expression*>* args) { 2674 void FullCodeGenerator::EmitArguments(ZoneList<Expression*>* args) {
2672 ASSERT(args->length() == 1); 2675 ASSERT(args->length() == 1);
2673 2676
2674 // ArgumentsAccessStub expects the key in edx and the formal 2677 // ArgumentsAccessStub expects the key in edx and the formal
2675 // parameter count in r0. 2678 // parameter count in r0.
2676 VisitForAccumulatorValue(args->at(0)); 2679 VisitForAccumulatorValue(args->at(0));
2677 __ mov(r1, r0); 2680 __ mov(r1, r0);
2678 __ mov(r0, Operand(Smi::FromInt(scope()->num_parameters()))); 2681 __ mov(r0, Operand(Smi::FromInt(info_->scope()->num_parameters())));
2679 ArgumentsAccessStub stub(ArgumentsAccessStub::READ_ELEMENT); 2682 ArgumentsAccessStub stub(ArgumentsAccessStub::READ_ELEMENT);
2680 __ CallStub(&stub); 2683 __ CallStub(&stub);
2681 context()->Plug(r0); 2684 context()->Plug(r0);
2682 } 2685 }
2683 2686
2684 2687
2685 void FullCodeGenerator::EmitArgumentsLength(ZoneList<Expression*>* args) { 2688 void FullCodeGenerator::EmitArgumentsLength(ZoneList<Expression*>* args) {
2686 ASSERT(args->length() == 0); 2689 ASSERT(args->length() == 0);
2687 2690
2688 Label exit; 2691 Label exit;
2689 // Get the number of formal parameters. 2692 // Get the number of formal parameters.
2690 __ mov(r0, Operand(Smi::FromInt(scope()->num_parameters()))); 2693 __ mov(r0, Operand(Smi::FromInt(info_->scope()->num_parameters())));
2691 2694
2692 // Check if the calling frame is an arguments adaptor frame. 2695 // Check if the calling frame is an arguments adaptor frame.
2693 __ ldr(r2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); 2696 __ ldr(r2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
2694 __ ldr(r3, MemOperand(r2, StandardFrameConstants::kContextOffset)); 2697 __ ldr(r3, MemOperand(r2, StandardFrameConstants::kContextOffset));
2695 __ cmp(r3, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); 2698 __ cmp(r3, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
2696 __ b(ne, &exit); 2699 __ b(ne, &exit);
2697 2700
2698 // Arguments adaptor case: Read the arguments length from the 2701 // Arguments adaptor case: Read the arguments length from the
2699 // adaptor frame. 2702 // adaptor frame.
2700 __ ldr(r0, MemOperand(r2, ArgumentsAdaptorFrameConstants::kLengthOffset)); 2703 __ ldr(r0, MemOperand(r2, ArgumentsAdaptorFrameConstants::kLengthOffset));
(...skipping 1525 matching lines...) Expand 10 before | Expand all | Expand 10 after
4226 // as their closure, not the anonymous closure containing the global 4229 // as their closure, not the anonymous closure containing the global
4227 // code. Pass a smi sentinel and let the runtime look up the empty 4230 // code. Pass a smi sentinel and let the runtime look up the empty
4228 // function. 4231 // function.
4229 __ mov(ip, Operand(Smi::FromInt(0))); 4232 __ mov(ip, Operand(Smi::FromInt(0)));
4230 } else if (scope()->is_eval_scope()) { 4233 } else if (scope()->is_eval_scope()) {
4231 // Contexts created by a call to eval have the same closure as the 4234 // Contexts created by a call to eval have the same closure as the
4232 // context calling eval, not the anonymous closure containing the eval 4235 // context calling eval, not the anonymous closure containing the eval
4233 // code. Fetch it from the context. 4236 // code. Fetch it from the context.
4234 __ ldr(ip, ContextOperand(cp, Context::CLOSURE_INDEX)); 4237 __ ldr(ip, ContextOperand(cp, Context::CLOSURE_INDEX));
4235 } else { 4238 } else {
4236 ASSERT(scope()->is_function_scope()); 4239 ASSERT(scope()->is_function_scope() || scope()->is_catch_scope());
4237 __ ldr(ip, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 4240 __ ldr(ip, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
4238 } 4241 }
4239 __ push(ip); 4242 __ push(ip);
4240 } 4243 }
4241 4244
4242 4245
4243 // ---------------------------------------------------------------------------- 4246 // ----------------------------------------------------------------------------
4244 // Non-local control flow support. 4247 // Non-local control flow support.
4245 4248
4246 void FullCodeGenerator::EnterFinallyBlock() { 4249 void FullCodeGenerator::EnterFinallyBlock() {
(...skipping 19 matching lines...) Expand all
4266 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. 4269 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value.
4267 __ add(pc, r1, Operand(masm_->CodeObject())); 4270 __ add(pc, r1, Operand(masm_->CodeObject()));
4268 } 4271 }
4269 4272
4270 4273
4271 #undef __ 4274 #undef __
4272 4275
4273 } } // namespace v8::internal 4276 } } // namespace v8::internal
4274 4277
4275 #endif // V8_TARGET_ARCH_ARM 4278 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « no previous file | src/ast.h » ('j') | src/full-codegen.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698