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

Side by Side Diff: src/ia32/codegen-ia32.cc

Issue 566008: Incorporate the arguments to the code generator constructors and their (Closed)
Patch Set: Incorporate the arguments to the code generator constructors and their... Created 10 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
« no previous file with comments | « src/ia32/codegen-ia32.h ('k') | src/ia32/fast-codegen-ia32.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 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 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 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
96 96
97 CodeGenState::~CodeGenState() { 97 CodeGenState::~CodeGenState() {
98 ASSERT(owner_->state() == this); 98 ASSERT(owner_->state() == this);
99 owner_->set_state(previous_); 99 owner_->set_state(previous_);
100 } 100 }
101 101
102 102
103 // ------------------------------------------------------------------------- 103 // -------------------------------------------------------------------------
104 // CodeGenerator implementation 104 // CodeGenerator implementation
105 105
106 CodeGenerator::CodeGenerator(MacroAssembler* masm, 106 CodeGenerator::CodeGenerator(MacroAssembler* masm)
107 Handle<Script> script, 107 : deferred_(8),
108 bool is_eval)
109 : is_eval_(is_eval),
110 script_(script),
111 deferred_(8),
112 masm_(masm), 108 masm_(masm),
113 scope_(NULL), 109 info_(NULL),
114 frame_(NULL), 110 frame_(NULL),
115 allocator_(NULL), 111 allocator_(NULL),
116 state_(NULL), 112 state_(NULL),
117 loop_nesting_(0), 113 loop_nesting_(0),
118 function_return_is_shadowed_(false), 114 function_return_is_shadowed_(false),
119 in_spilled_code_(false) { 115 in_spilled_code_(false) {
120 } 116 }
121 117
122 118
119 Scope* CodeGenerator::scope() { return info_->function()->scope(); }
120
121
123 // Calling conventions: 122 // Calling conventions:
124 // ebp: caller's frame pointer 123 // ebp: caller's frame pointer
125 // esp: stack pointer 124 // esp: stack pointer
126 // edi: called JS function 125 // edi: called JS function
127 // esi: callee's context 126 // esi: callee's context
128 127
129 void CodeGenerator::Generate(FunctionLiteral* fun, 128 void CodeGenerator::Generate(CompilationInfo* info, Mode mode) {
130 Mode mode,
131 CompilationInfo* info) {
132 // Record the position for debugging purposes. 129 // Record the position for debugging purposes.
133 CodeForFunctionPosition(fun); 130 CodeForFunctionPosition(info->function());
134
135 ZoneList<Statement*>* body = fun->body();
136 131
137 // Initialize state. 132 // Initialize state.
138 ASSERT(scope_ == NULL); 133 info_ = info;
139 scope_ = fun->scope();
140 ASSERT(allocator_ == NULL); 134 ASSERT(allocator_ == NULL);
141 RegisterAllocator register_allocator(this); 135 RegisterAllocator register_allocator(this);
142 allocator_ = &register_allocator; 136 allocator_ = &register_allocator;
143 ASSERT(frame_ == NULL); 137 ASSERT(frame_ == NULL);
144 frame_ = new VirtualFrame(); 138 frame_ = new VirtualFrame();
145 set_in_spilled_code(false); 139 set_in_spilled_code(false);
146 140
147 // Adjust for function-level loop nesting. 141 // Adjust for function-level loop nesting.
148 loop_nesting_ += info->loop_nesting(); 142 loop_nesting_ += info->loop_nesting();
149 143
150 JumpTarget::set_compiling_deferred_code(false); 144 JumpTarget::set_compiling_deferred_code(false);
151 145
152 #ifdef DEBUG 146 #ifdef DEBUG
153 if (strlen(FLAG_stop_at) > 0 && 147 if (strlen(FLAG_stop_at) > 0 &&
154 fun->name()->IsEqualTo(CStrVector(FLAG_stop_at))) { 148 info->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) {
155 frame_->SpillAll(); 149 frame_->SpillAll();
156 __ int3(); 150 __ int3();
157 } 151 }
158 #endif 152 #endif
159 153
160 // New scope to get automatic timing calculation. 154 // New scope to get automatic timing calculation.
161 { // NOLINT 155 { // NOLINT
162 HistogramTimerScope codegen_timer(&Counters::code_generation); 156 HistogramTimerScope codegen_timer(&Counters::code_generation);
163 CodeGenState state(this); 157 CodeGenState state(this);
164 158
165 // Entry: 159 // Entry:
166 // Stack: receiver, arguments, return address. 160 // Stack: receiver, arguments, return address.
167 // ebp: caller's frame pointer 161 // ebp: caller's frame pointer
168 // esp: stack pointer 162 // esp: stack pointer
169 // edi: called JS function 163 // edi: called JS function
170 // esi: callee's context 164 // esi: callee's context
171 allocator_->Initialize(); 165 allocator_->Initialize();
172 166
173 if (mode == PRIMARY) { 167 if (mode == PRIMARY) {
174 frame_->Enter(); 168 frame_->Enter();
175 169
176 // Allocate space for locals and initialize them. 170 // Allocate space for locals and initialize them.
177 frame_->AllocateStackSlots(); 171 frame_->AllocateStackSlots();
178 172
179 // Allocate the local context if needed. 173 // Allocate the local context if needed.
180 int heap_slots = scope_->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; 174 int heap_slots = scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
181 if (heap_slots > 0) { 175 if (heap_slots > 0) {
182 Comment cmnt(masm_, "[ allocate local context"); 176 Comment cmnt(masm_, "[ allocate local context");
183 // Allocate local context. 177 // Allocate local context.
184 // Get outer context and create a new context based on it. 178 // Get outer context and create a new context based on it.
185 frame_->PushFunction(); 179 frame_->PushFunction();
186 Result context; 180 Result context;
187 if (heap_slots <= FastNewContextStub::kMaximumSlots) { 181 if (heap_slots <= FastNewContextStub::kMaximumSlots) {
188 FastNewContextStub stub(heap_slots); 182 FastNewContextStub stub(heap_slots);
189 context = frame_->CallStub(&stub, 1); 183 context = frame_->CallStub(&stub, 1);
190 } else { 184 } else {
191 context = frame_->CallRuntime(Runtime::kNewContext, 1); 185 context = frame_->CallRuntime(Runtime::kNewContext, 1);
192 } 186 }
193 187
194 // Update context local. 188 // Update context local.
195 frame_->SaveContextRegister(); 189 frame_->SaveContextRegister();
196 190
197 // Verify that the runtime call result and esi agree. 191 // Verify that the runtime call result and esi agree.
198 if (FLAG_debug_code) { 192 if (FLAG_debug_code) {
199 __ cmp(context.reg(), Operand(esi)); 193 __ cmp(context.reg(), Operand(esi));
200 __ Assert(equal, "Runtime::NewContext should end up in esi"); 194 __ Assert(equal, "Runtime::NewContext should end up in esi");
201 } 195 }
202 } 196 }
203 197
204 // TODO(1241774): Improve this code: 198 // TODO(1241774): Improve this code:
205 // 1) only needed if we have a context 199 // 1) only needed if we have a context
206 // 2) no need to recompute context ptr every single time 200 // 2) no need to recompute context ptr every single time
207 // 3) don't copy parameter operand code from SlotOperand! 201 // 3) don't copy parameter operand code from SlotOperand!
208 { 202 {
209 Comment cmnt2(masm_, "[ copy context parameters into .context"); 203 Comment cmnt2(masm_, "[ copy context parameters into .context");
210
211 // Note that iteration order is relevant here! If we have the same 204 // Note that iteration order is relevant here! If we have the same
212 // parameter twice (e.g., function (x, y, x)), and that parameter 205 // parameter twice (e.g., function (x, y, x)), and that parameter
213 // needs to be copied into the context, it must be the last argument 206 // needs to be copied into the context, it must be the last argument
214 // passed to the parameter that needs to be copied. This is a rare 207 // passed to the parameter that needs to be copied. This is a rare
215 // case so we don't check for it, instead we rely on the copying 208 // case so we don't check for it, instead we rely on the copying
216 // order: such a parameter is copied repeatedly into the same 209 // order: such a parameter is copied repeatedly into the same
217 // context location and thus the last value is what is seen inside 210 // context location and thus the last value is what is seen inside
218 // the function. 211 // the function.
219 for (int i = 0; i < scope_->num_parameters(); i++) { 212 for (int i = 0; i < scope()->num_parameters(); i++) {
220 Variable* par = scope_->parameter(i); 213 Variable* par = scope()->parameter(i);
221 Slot* slot = par->slot(); 214 Slot* slot = par->slot();
222 if (slot != NULL && slot->type() == Slot::CONTEXT) { 215 if (slot != NULL && slot->type() == Slot::CONTEXT) {
223 // The use of SlotOperand below is safe in unspilled code 216 // The use of SlotOperand below is safe in unspilled code
224 // because the slot is guaranteed to be a context slot. 217 // because the slot is guaranteed to be a context slot.
225 // 218 //
226 // There are no parameters in the global scope. 219 // There are no parameters in the global scope.
227 ASSERT(!scope_->is_global_scope()); 220 ASSERT(!scope()->is_global_scope());
228 frame_->PushParameterAt(i); 221 frame_->PushParameterAt(i);
229 Result value = frame_->Pop(); 222 Result value = frame_->Pop();
230 value.ToRegister(); 223 value.ToRegister();
231 224
232 // SlotOperand loads context.reg() with the context object 225 // SlotOperand loads context.reg() with the context object
233 // stored to, used below in RecordWrite. 226 // stored to, used below in RecordWrite.
234 Result context = allocator_->Allocate(); 227 Result context = allocator_->Allocate();
235 ASSERT(context.is_valid()); 228 ASSERT(context.is_valid());
236 __ mov(SlotOperand(slot, context.reg()), value.reg()); 229 __ mov(SlotOperand(slot, context.reg()), value.reg());
237 int offset = FixedArray::kHeaderSize + slot->index() * kPointerSize; 230 int offset = FixedArray::kHeaderSize + slot->index() * kPointerSize;
238 Result scratch = allocator_->Allocate(); 231 Result scratch = allocator_->Allocate();
239 ASSERT(scratch.is_valid()); 232 ASSERT(scratch.is_valid());
240 frame_->Spill(context.reg()); 233 frame_->Spill(context.reg());
241 frame_->Spill(value.reg()); 234 frame_->Spill(value.reg());
242 __ RecordWrite(context.reg(), offset, value.reg(), scratch.reg()); 235 __ RecordWrite(context.reg(), offset, value.reg(), scratch.reg());
243 } 236 }
244 } 237 }
245 } 238 }
246 239
247 // Store the arguments object. This must happen after context 240 // Store the arguments object. This must happen after context
248 // initialization because the arguments object may be stored in 241 // initialization because the arguments object may be stored in
249 // the context. 242 // the context.
250 if (ArgumentsMode() != NO_ARGUMENTS_ALLOCATION) { 243 if (ArgumentsMode() != NO_ARGUMENTS_ALLOCATION) {
251 StoreArgumentsObject(true); 244 StoreArgumentsObject(true);
252 } 245 }
253 246
254 // Initialize ThisFunction reference if present. 247 // Initialize ThisFunction reference if present.
255 if (scope_->is_function_scope() && scope_->function() != NULL) { 248 if (scope()->is_function_scope() && scope()->function() != NULL) {
256 frame_->Push(Factory::the_hole_value()); 249 frame_->Push(Factory::the_hole_value());
257 StoreToSlot(scope_->function()->slot(), NOT_CONST_INIT); 250 StoreToSlot(scope()->function()->slot(), NOT_CONST_INIT);
258 } 251 }
259 } else { 252 } else {
260 // When used as the secondary compiler for splitting, ebp, esi, 253 // When used as the secondary compiler for splitting, ebp, esi,
261 // and edi have been pushed on the stack. Adjust the virtual 254 // and edi have been pushed on the stack. Adjust the virtual
262 // frame to match this state. 255 // frame to match this state.
263 frame_->Adjust(3); 256 frame_->Adjust(3);
264 allocator_->Unuse(edi); 257 allocator_->Unuse(edi);
265 } 258 }
266 259
267 // Initialize the function return target after the locals are set 260 // Initialize the function return target after the locals are set
268 // up, because it needs the expected frame height from the frame. 261 // up, because it needs the expected frame height from the frame.
269 function_return_.set_direction(JumpTarget::BIDIRECTIONAL); 262 function_return_.set_direction(JumpTarget::BIDIRECTIONAL);
270 function_return_is_shadowed_ = false; 263 function_return_is_shadowed_ = false;
271 264
272 // Generate code to 'execute' declarations and initialize functions 265 // Generate code to 'execute' declarations and initialize functions
273 // (source elements). In case of an illegal redeclaration we need to 266 // (source elements). In case of an illegal redeclaration we need to
274 // handle that instead of processing the declarations. 267 // handle that instead of processing the declarations.
275 if (scope_->HasIllegalRedeclaration()) { 268 if (scope()->HasIllegalRedeclaration()) {
276 Comment cmnt(masm_, "[ illegal redeclarations"); 269 Comment cmnt(masm_, "[ illegal redeclarations");
277 scope_->VisitIllegalRedeclaration(this); 270 scope()->VisitIllegalRedeclaration(this);
278 } else { 271 } else {
279 Comment cmnt(masm_, "[ declarations"); 272 Comment cmnt(masm_, "[ declarations");
280 ProcessDeclarations(scope_->declarations()); 273 ProcessDeclarations(scope()->declarations());
281 // Bail out if a stack-overflow exception occurred when processing 274 // Bail out if a stack-overflow exception occurred when processing
282 // declarations. 275 // declarations.
283 if (HasStackOverflow()) return; 276 if (HasStackOverflow()) return;
284 } 277 }
285 278
286 if (FLAG_trace) { 279 if (FLAG_trace) {
287 frame_->CallRuntime(Runtime::kTraceEnter, 0); 280 frame_->CallRuntime(Runtime::kTraceEnter, 0);
288 // Ignore the return value. 281 // Ignore the return value.
289 } 282 }
290 CheckStack(); 283 CheckStack();
291 284
292 // Compile the body of the function in a vanilla state. Don't 285 // Compile the body of the function in a vanilla state. Don't
293 // bother compiling all the code if the scope has an illegal 286 // bother compiling all the code if the scope has an illegal
294 // redeclaration. 287 // redeclaration.
295 if (!scope_->HasIllegalRedeclaration()) { 288 if (!scope()->HasIllegalRedeclaration()) {
296 Comment cmnt(masm_, "[ function body"); 289 Comment cmnt(masm_, "[ function body");
297 #ifdef DEBUG 290 #ifdef DEBUG
298 bool is_builtin = Bootstrapper::IsActive(); 291 bool is_builtin = Bootstrapper::IsActive();
299 bool should_trace = 292 bool should_trace =
300 is_builtin ? FLAG_trace_builtin_calls : FLAG_trace_calls; 293 is_builtin ? FLAG_trace_builtin_calls : FLAG_trace_calls;
301 if (should_trace) { 294 if (should_trace) {
302 frame_->CallRuntime(Runtime::kDebugTrace, 0); 295 frame_->CallRuntime(Runtime::kDebugTrace, 0);
303 // Ignore the return value. 296 // Ignore the return value.
304 } 297 }
305 #endif 298 #endif
306 VisitStatements(body); 299 VisitStatements(info->function()->body());
307 300
308 // Handle the return from the function. 301 // Handle the return from the function.
309 if (has_valid_frame()) { 302 if (has_valid_frame()) {
310 // If there is a valid frame, control flow can fall off the end of 303 // If there is a valid frame, control flow can fall off the end of
311 // the body. In that case there is an implicit return statement. 304 // the body. In that case there is an implicit return statement.
312 ASSERT(!function_return_is_shadowed_); 305 ASSERT(!function_return_is_shadowed_);
313 CodeForReturnPosition(fun); 306 CodeForReturnPosition(info->function());
314 frame_->PrepareForReturn(); 307 frame_->PrepareForReturn();
315 Result undefined(Factory::undefined_value()); 308 Result undefined(Factory::undefined_value());
316 if (function_return_.is_bound()) { 309 if (function_return_.is_bound()) {
317 function_return_.Jump(&undefined); 310 function_return_.Jump(&undefined);
318 } else { 311 } else {
319 function_return_.Bind(&undefined); 312 function_return_.Bind(&undefined);
320 GenerateReturnSequence(&undefined); 313 GenerateReturnSequence(&undefined);
321 } 314 }
322 } else if (function_return_.is_linked()) { 315 } else if (function_return_.is_linked()) {
323 // If the return target has dangling jumps to it, then we have not 316 // If the return target has dangling jumps to it, then we have not
(...skipping 22 matching lines...) Expand all
346 if (!HasStackOverflow()) { 339 if (!HasStackOverflow()) {
347 HistogramTimerScope deferred_timer(&Counters::deferred_code_generation); 340 HistogramTimerScope deferred_timer(&Counters::deferred_code_generation);
348 JumpTarget::set_compiling_deferred_code(true); 341 JumpTarget::set_compiling_deferred_code(true);
349 ProcessDeferred(); 342 ProcessDeferred();
350 JumpTarget::set_compiling_deferred_code(false); 343 JumpTarget::set_compiling_deferred_code(false);
351 } 344 }
352 345
353 // There is no need to delete the register allocator, it is a 346 // There is no need to delete the register allocator, it is a
354 // stack-allocated local. 347 // stack-allocated local.
355 allocator_ = NULL; 348 allocator_ = NULL;
356 scope_ = NULL;
357 } 349 }
358 350
359 351
360 Operand CodeGenerator::SlotOperand(Slot* slot, Register tmp) { 352 Operand CodeGenerator::SlotOperand(Slot* slot, Register tmp) {
361 // Currently, this assertion will fail if we try to assign to 353 // Currently, this assertion will fail if we try to assign to
362 // a constant variable that is constant because it is read-only 354 // a constant variable that is constant because it is read-only
363 // (such as the variable referring to a named function expression). 355 // (such as the variable referring to a named function expression).
364 // We need to implement assignments to read-only variables. 356 // We need to implement assignments to read-only variables.
365 // Ideally, we should do this during AST generation (by converting 357 // Ideally, we should do this during AST generation (by converting
366 // such assignments into expression statements); however, in general 358 // such assignments into expression statements); however, in general
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after
583 // For a variable that rewrites to a slot, we signal it is the immediate 575 // For a variable that rewrites to a slot, we signal it is the immediate
584 // subexpression of a typeof. 576 // subexpression of a typeof.
585 LoadFromSlotCheckForArguments(variable->slot(), INSIDE_TYPEOF); 577 LoadFromSlotCheckForArguments(variable->slot(), INSIDE_TYPEOF);
586 } else { 578 } else {
587 // Anything else can be handled normally. 579 // Anything else can be handled normally.
588 Load(expr); 580 Load(expr);
589 } 581 }
590 } 582 }
591 583
592 584
593 ArgumentsAllocationMode CodeGenerator::ArgumentsMode() const { 585 ArgumentsAllocationMode CodeGenerator::ArgumentsMode() {
594 if (scope_->arguments() == NULL) return NO_ARGUMENTS_ALLOCATION; 586 if (scope()->arguments() == NULL) return NO_ARGUMENTS_ALLOCATION;
595 ASSERT(scope_->arguments_shadow() != NULL); 587 ASSERT(scope()->arguments_shadow() != NULL);
596 // We don't want to do lazy arguments allocation for functions that 588 // We don't want to do lazy arguments allocation for functions that
597 // have heap-allocated contexts, because it interfers with the 589 // have heap-allocated contexts, because it interfers with the
598 // uninitialized const tracking in the context objects. 590 // uninitialized const tracking in the context objects.
599 return (scope_->num_heap_slots() > 0) 591 return (scope()->num_heap_slots() > 0)
600 ? EAGER_ARGUMENTS_ALLOCATION 592 ? EAGER_ARGUMENTS_ALLOCATION
601 : LAZY_ARGUMENTS_ALLOCATION; 593 : LAZY_ARGUMENTS_ALLOCATION;
602 } 594 }
603 595
604 596
605 Result CodeGenerator::StoreArgumentsObject(bool initial) { 597 Result CodeGenerator::StoreArgumentsObject(bool initial) {
606 ArgumentsAllocationMode mode = ArgumentsMode(); 598 ArgumentsAllocationMode mode = ArgumentsMode();
607 ASSERT(mode != NO_ARGUMENTS_ALLOCATION); 599 ASSERT(mode != NO_ARGUMENTS_ALLOCATION);
608 600
609 Comment cmnt(masm_, "[ store arguments object"); 601 Comment cmnt(masm_, "[ store arguments object");
610 if (mode == LAZY_ARGUMENTS_ALLOCATION && initial) { 602 if (mode == LAZY_ARGUMENTS_ALLOCATION && initial) {
611 // When using lazy arguments allocation, we store the hole value 603 // When using lazy arguments allocation, we store the hole value
612 // as a sentinel indicating that the arguments object hasn't been 604 // as a sentinel indicating that the arguments object hasn't been
613 // allocated yet. 605 // allocated yet.
614 frame_->Push(Factory::the_hole_value()); 606 frame_->Push(Factory::the_hole_value());
615 } else { 607 } else {
616 ArgumentsAccessStub stub(ArgumentsAccessStub::NEW_OBJECT); 608 ArgumentsAccessStub stub(ArgumentsAccessStub::NEW_OBJECT);
617 frame_->PushFunction(); 609 frame_->PushFunction();
618 frame_->PushReceiverSlotAddress(); 610 frame_->PushReceiverSlotAddress();
619 frame_->Push(Smi::FromInt(scope_->num_parameters())); 611 frame_->Push(Smi::FromInt(scope()->num_parameters()));
620 Result result = frame_->CallStub(&stub, 3); 612 Result result = frame_->CallStub(&stub, 3);
621 frame_->Push(&result); 613 frame_->Push(&result);
622 } 614 }
623 615
624 Variable* arguments = scope_->arguments()->var(); 616 Variable* arguments = scope()->arguments()->var();
625 Variable* shadow = scope_->arguments_shadow()->var(); 617 Variable* shadow = scope()->arguments_shadow()->var();
626 ASSERT(arguments != NULL && arguments->slot() != NULL); 618 ASSERT(arguments != NULL && arguments->slot() != NULL);
627 ASSERT(shadow != NULL && shadow->slot() != NULL); 619 ASSERT(shadow != NULL && shadow->slot() != NULL);
628 JumpTarget done; 620 JumpTarget done;
629 bool skip_arguments = false; 621 bool skip_arguments = false;
630 if (mode == LAZY_ARGUMENTS_ALLOCATION && !initial) { 622 if (mode == LAZY_ARGUMENTS_ALLOCATION && !initial) {
631 // We have to skip storing into the arguments slot if it has already 623 // We have to skip storing into the arguments slot if it has already
632 // been written to. This can happen if the a function has a local 624 // been written to. This can happen if the a function has a local
633 // variable named 'arguments'. 625 // variable named 'arguments'.
634 LoadFromSlot(arguments->slot(), NOT_INSIDE_TYPEOF); 626 LoadFromSlot(arguments->slot(), NOT_INSIDE_TYPEOF);
635 Result probe = frame_->Pop(); 627 Result probe = frame_->Pop();
(...skipping 1701 matching lines...) Expand 10 before | Expand all | Expand 10 after
2337 Load(applicand); 2329 Load(applicand);
2338 Handle<String> name = Factory::LookupAsciiSymbol("apply"); 2330 Handle<String> name = Factory::LookupAsciiSymbol("apply");
2339 frame()->Push(name); 2331 frame()->Push(name);
2340 Result answer = frame()->CallLoadIC(RelocInfo::CODE_TARGET); 2332 Result answer = frame()->CallLoadIC(RelocInfo::CODE_TARGET);
2341 __ nop(); 2333 __ nop();
2342 frame()->Push(&answer); 2334 frame()->Push(&answer);
2343 2335
2344 // Load the receiver and the existing arguments object onto the 2336 // Load the receiver and the existing arguments object onto the
2345 // expression stack. Avoid allocating the arguments object here. 2337 // expression stack. Avoid allocating the arguments object here.
2346 Load(receiver); 2338 Load(receiver);
2347 LoadFromSlot(scope_->arguments()->var()->slot(), NOT_INSIDE_TYPEOF); 2339 LoadFromSlot(scope()->arguments()->var()->slot(), NOT_INSIDE_TYPEOF);
2348 2340
2349 // Emit the source position information after having loaded the 2341 // Emit the source position information after having loaded the
2350 // receiver and the arguments. 2342 // receiver and the arguments.
2351 CodeForSourcePosition(position); 2343 CodeForSourcePosition(position);
2352 // Contents of frame at this point: 2344 // Contents of frame at this point:
2353 // Frame[0]: arguments object of the current function or the hole. 2345 // Frame[0]: arguments object of the current function or the hole.
2354 // Frame[1]: receiver 2346 // Frame[1]: receiver
2355 // Frame[2]: applicand.apply 2347 // Frame[2]: applicand.apply
2356 // Frame[3]: applicand. 2348 // Frame[3]: applicand.
2357 2349
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
2417 // Copy the arguments to this function possibly from the 2409 // Copy the arguments to this function possibly from the
2418 // adaptor frame below it. 2410 // adaptor frame below it.
2419 Label invoke, adapted; 2411 Label invoke, adapted;
2420 __ mov(edx, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); 2412 __ mov(edx, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
2421 __ mov(ecx, Operand(edx, StandardFrameConstants::kContextOffset)); 2413 __ mov(ecx, Operand(edx, StandardFrameConstants::kContextOffset));
2422 __ cmp(Operand(ecx), 2414 __ cmp(Operand(ecx),
2423 Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); 2415 Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
2424 __ j(equal, &adapted); 2416 __ j(equal, &adapted);
2425 2417
2426 // No arguments adaptor frame. Copy fixed number of arguments. 2418 // No arguments adaptor frame. Copy fixed number of arguments.
2427 __ mov(eax, Immediate(scope_->num_parameters())); 2419 __ mov(eax, Immediate(scope()->num_parameters()));
2428 for (int i = 0; i < scope_->num_parameters(); i++) { 2420 for (int i = 0; i < scope()->num_parameters(); i++) {
2429 __ push(frame_->ParameterAt(i)); 2421 __ push(frame_->ParameterAt(i));
2430 } 2422 }
2431 __ jmp(&invoke); 2423 __ jmp(&invoke);
2432 2424
2433 // Arguments adaptor frame present. Copy arguments from there, but 2425 // Arguments adaptor frame present. Copy arguments from there, but
2434 // avoid copying too many arguments to avoid stack overflows. 2426 // avoid copying too many arguments to avoid stack overflows.
2435 __ bind(&adapted); 2427 __ bind(&adapted);
2436 static const uint32_t kArgumentsLimit = 1 * KB; 2428 static const uint32_t kArgumentsLimit = 1 * KB;
2437 __ mov(eax, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset)); 2429 __ mov(eax, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset));
2438 __ SmiUntag(eax); 2430 __ SmiUntag(eax);
(...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after
2824 } 2816 }
2825 return_value->ToRegister(eax); 2817 return_value->ToRegister(eax);
2826 2818
2827 // Add a label for checking the size of the code used for returning. 2819 // Add a label for checking the size of the code used for returning.
2828 Label check_exit_codesize; 2820 Label check_exit_codesize;
2829 masm_->bind(&check_exit_codesize); 2821 masm_->bind(&check_exit_codesize);
2830 2822
2831 // Leave the frame and return popping the arguments and the 2823 // Leave the frame and return popping the arguments and the
2832 // receiver. 2824 // receiver.
2833 frame_->Exit(); 2825 frame_->Exit();
2834 masm_->ret((scope_->num_parameters() + 1) * kPointerSize); 2826 masm_->ret((scope()->num_parameters() + 1) * kPointerSize);
2835 DeleteFrame(); 2827 DeleteFrame();
2836 2828
2837 #ifdef ENABLE_DEBUGGER_SUPPORT 2829 #ifdef ENABLE_DEBUGGER_SUPPORT
2838 // Check that the size of the code used for returning matches what is 2830 // Check that the size of the code used for returning matches what is
2839 // expected by the debugger. 2831 // expected by the debugger.
2840 ASSERT_EQ(Assembler::kJSReturnSequenceLength, 2832 ASSERT_EQ(Assembler::kJSReturnSequenceLength,
2841 masm_->SizeOfCodeGeneratedSince(&check_exit_codesize)); 2833 masm_->SizeOfCodeGeneratedSince(&check_exit_codesize));
2842 #endif 2834 #endif
2843 } 2835 }
2844 2836
(...skipping 1100 matching lines...) Expand 10 before | Expand all | Expand 10 after
3945 frame_->Push(&result); 3937 frame_->Push(&result);
3946 } 3938 }
3947 } 3939 }
3948 3940
3949 3941
3950 void CodeGenerator::VisitFunctionLiteral(FunctionLiteral* node) { 3942 void CodeGenerator::VisitFunctionLiteral(FunctionLiteral* node) {
3951 Comment cmnt(masm_, "[ FunctionLiteral"); 3943 Comment cmnt(masm_, "[ FunctionLiteral");
3952 3944
3953 // Build the function boilerplate and instantiate it. 3945 // Build the function boilerplate and instantiate it.
3954 Handle<JSFunction> boilerplate = 3946 Handle<JSFunction> boilerplate =
3955 Compiler::BuildBoilerplate(node, script_, this); 3947 Compiler::BuildBoilerplate(node, script(), this);
3956 // Check for stack-overflow exception. 3948 // Check for stack-overflow exception.
3957 if (HasStackOverflow()) return; 3949 if (HasStackOverflow()) return;
3958 InstantiateBoilerplate(boilerplate); 3950 InstantiateBoilerplate(boilerplate);
3959 } 3951 }
3960 3952
3961 3953
3962 void CodeGenerator::VisitFunctionBoilerplateLiteral( 3954 void CodeGenerator::VisitFunctionBoilerplateLiteral(
3963 FunctionBoilerplateLiteral* node) { 3955 FunctionBoilerplateLiteral* node) {
3964 Comment cmnt(masm_, "[ FunctionBoilerplateLiteral"); 3956 Comment cmnt(masm_, "[ FunctionBoilerplateLiteral");
3965 InstantiateBoilerplate(node->boilerplate()); 3957 InstantiateBoilerplate(node->boilerplate());
(...skipping 1304 matching lines...) Expand 10 before | Expand all | Expand 10 after
5270 Immediate(Smi::FromInt(StackFrame::CONSTRUCT))); 5262 Immediate(Smi::FromInt(StackFrame::CONSTRUCT)));
5271 fp.Unuse(); 5263 fp.Unuse();
5272 destination()->Split(equal); 5264 destination()->Split(equal);
5273 } 5265 }
5274 5266
5275 5267
5276 void CodeGenerator::GenerateArgumentsLength(ZoneList<Expression*>* args) { 5268 void CodeGenerator::GenerateArgumentsLength(ZoneList<Expression*>* args) {
5277 ASSERT(args->length() == 0); 5269 ASSERT(args->length() == 0);
5278 // ArgumentsAccessStub takes the parameter count as an input argument 5270 // ArgumentsAccessStub takes the parameter count as an input argument
5279 // in register eax. Create a constant result for it. 5271 // in register eax. Create a constant result for it.
5280 Result count(Handle<Smi>(Smi::FromInt(scope_->num_parameters()))); 5272 Result count(Handle<Smi>(Smi::FromInt(scope()->num_parameters())));
5281 // Call the shared stub to get to the arguments.length. 5273 // Call the shared stub to get to the arguments.length.
5282 ArgumentsAccessStub stub(ArgumentsAccessStub::READ_LENGTH); 5274 ArgumentsAccessStub stub(ArgumentsAccessStub::READ_LENGTH);
5283 Result result = frame_->CallStub(&stub, &count); 5275 Result result = frame_->CallStub(&stub, &count);
5284 frame_->Push(&result); 5276 frame_->Push(&result);
5285 } 5277 }
5286 5278
5287 5279
5288 void CodeGenerator::GenerateClassOf(ZoneList<Expression*>* args) { 5280 void CodeGenerator::GenerateClassOf(ZoneList<Expression*>* args) {
5289 ASSERT(args->length() == 1); 5281 ASSERT(args->length() == 1);
5290 JumpTarget leave, null, function, non_function_constructor; 5282 JumpTarget leave, null, function, non_function_constructor;
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
5417 5409
5418 5410
5419 void CodeGenerator::GenerateArgumentsAccess(ZoneList<Expression*>* args) { 5411 void CodeGenerator::GenerateArgumentsAccess(ZoneList<Expression*>* args) {
5420 ASSERT(args->length() == 1); 5412 ASSERT(args->length() == 1);
5421 5413
5422 // ArgumentsAccessStub expects the key in edx and the formal 5414 // ArgumentsAccessStub expects the key in edx and the formal
5423 // parameter count in eax. 5415 // parameter count in eax.
5424 Load(args->at(0)); 5416 Load(args->at(0));
5425 Result key = frame_->Pop(); 5417 Result key = frame_->Pop();
5426 // Explicitly create a constant result. 5418 // Explicitly create a constant result.
5427 Result count(Handle<Smi>(Smi::FromInt(scope_->num_parameters()))); 5419 Result count(Handle<Smi>(Smi::FromInt(scope()->num_parameters())));
5428 // Call the shared stub to get to arguments[key]. 5420 // Call the shared stub to get to arguments[key].
5429 ArgumentsAccessStub stub(ArgumentsAccessStub::READ_ELEMENT); 5421 ArgumentsAccessStub stub(ArgumentsAccessStub::READ_ELEMENT);
5430 Result result = frame_->CallStub(&stub, &key, &count); 5422 Result result = frame_->CallStub(&stub, &key, &count);
5431 frame_->Push(&result); 5423 frame_->Push(&result);
5432 } 5424 }
5433 5425
5434 5426
5435 void CodeGenerator::GenerateObjectEquals(ZoneList<Expression*>* args) { 5427 void CodeGenerator::GenerateObjectEquals(ZoneList<Expression*>* args) {
5436 ASSERT(args->length() == 2); 5428 ASSERT(args->length() == 2);
5437 5429
(...skipping 4664 matching lines...) Expand 10 before | Expand all | Expand 10 after
10102 10094
10103 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) 10095 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater)
10104 // tagged as a small integer. 10096 // tagged as a small integer.
10105 __ bind(&runtime); 10097 __ bind(&runtime);
10106 __ TailCallRuntime(ExternalReference(Runtime::kStringCompare), 2, 1); 10098 __ TailCallRuntime(ExternalReference(Runtime::kStringCompare), 2, 1);
10107 } 10099 }
10108 10100
10109 #undef __ 10101 #undef __
10110 10102
10111 } } // namespace v8::internal 10103 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ia32/codegen-ia32.h ('k') | src/ia32/fast-codegen-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698