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

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

Issue 9182: Emit pushes and pops through the virtual frame on ARM. Merging of... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 12 years, 1 month 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
« src/codegen-arm.cc ('K') | « src/codegen-arm.cc ('k') | 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 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 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 249 matching lines...) Expand 10 before | Expand all | Expand 10 after
260 __ CallRuntime(Runtime::kNewContext, 1); // eax holds the result 260 __ CallRuntime(Runtime::kNewContext, 1); // eax holds the result
261 261
262 if (kDebug) { 262 if (kDebug) {
263 Label verified_true; 263 Label verified_true;
264 // Verify eax and esi are the same in debug mode 264 // Verify eax and esi are the same in debug mode
265 __ cmp(eax, Operand(esi)); 265 __ cmp(eax, Operand(esi));
266 __ j(equal, &verified_true); 266 __ j(equal, &verified_true);
267 __ int3(); 267 __ int3();
268 __ bind(&verified_true); 268 __ bind(&verified_true);
269 } 269 }
270
271 // Update context local. 270 // Update context local.
272 __ mov(frame_->Context(), esi); 271 __ mov(frame_->Context(), esi);
273 // Restore the arguments array pointer, if any.
274 } 272 }
275 273
276 // TODO(1241774): Improve this code: 274 // TODO(1241774): Improve this code:
277 // 1) only needed if we have a context 275 // 1) only needed if we have a context
278 // 2) no need to recompute context ptr every single time 276 // 2) no need to recompute context ptr every single time
279 // 3) don't copy parameter operand code from SlotOperand! 277 // 3) don't copy parameter operand code from SlotOperand!
280 { 278 {
281 Comment cmnt2(masm_, "[ copy context parameters into .context"); 279 Comment cmnt2(masm_, "[ copy context parameters into .context");
282 280
283 // Note that iteration order is relevant here! If we have the same 281 // Note that iteration order is relevant here! If we have the same
(...skipping 19 matching lines...) Expand all
303 __ mov(SlotOperand(slot, ecx), eax); 301 __ mov(SlotOperand(slot, ecx), eax);
304 int offset = FixedArray::kHeaderSize + slot->index() * kPointerSize; 302 int offset = FixedArray::kHeaderSize + slot->index() * kPointerSize;
305 __ RecordWrite(ecx, offset, eax, ebx); 303 __ RecordWrite(ecx, offset, eax, ebx);
306 } 304 }
307 } 305 }
308 } 306 }
309 307
310 // This section stores the pointer to the arguments object that 308 // This section stores the pointer to the arguments object that
311 // was allocated and copied into above. If the address was not 309 // was allocated and copied into above. If the address was not
312 // saved to TOS, we push ecx onto the stack. 310 // saved to TOS, we push ecx onto the stack.
313 311 //
314 // Store the arguments object. 312 // Store the arguments object. This must happen after context
315 // This must happen after context initialization because 313 // initialization because the arguments object may be stored in the
316 // the arguments object may be stored in the context 314 // context.
317 if (arguments_object_allocated) { 315 if (arguments_object_allocated) {
318 ASSERT(scope_->arguments() != NULL); 316 ASSERT(scope_->arguments() != NULL);
319 ASSERT(scope_->arguments_shadow() != NULL); 317 ASSERT(scope_->arguments_shadow() != NULL);
320 Comment cmnt(masm_, "[ store arguments object"); 318 Comment cmnt(masm_, "[ store arguments object");
321 { Reference shadow_ref(this, scope_->arguments_shadow()); 319 { Reference shadow_ref(this, scope_->arguments_shadow());
322 ASSERT(shadow_ref.is_slot()); 320 ASSERT(shadow_ref.is_slot());
323 { Reference arguments_ref(this, scope_->arguments()); 321 { Reference arguments_ref(this, scope_->arguments());
324 ASSERT(arguments_ref.is_slot()); 322 ASSERT(arguments_ref.is_slot());
325 // If the newly-allocated arguments object is already on the 323 // If the newly-allocated arguments object is already on the
326 // stack, we make use of the convenient property that references 324 // stack, we make use of the convenient property that references
327 // representing slots take up no space on the expression stack 325 // representing slots take up no space on the expression stack
328 // (ie, it doesn't matter that the stored value is actually below 326 // (ie, it doesn't matter that the stored value is actually below
329 // the reference). 327 // the reference).
330 // 328 //
331 // If the newly-allocated argument object is not already on 329 // If the newly-allocated argument object is not already on
332 // the stack, we rely on the property that loading a 330 // the stack, we rely on the property that loading a
333 // zero-sized reference will not clobber the ecx register. 331 // zero-sized reference will not clobber the ecx register.
334 if (!arguments_object_saved) { 332 if (!arguments_object_saved) {
335 frame_->Push(ecx); 333 frame_->Push(ecx);
336 } 334 }
337 arguments_ref.SetValue(NOT_CONST_INIT); 335 arguments_ref.SetValue(NOT_CONST_INIT);
338 } 336 }
339 shadow_ref.SetValue(NOT_CONST_INIT); 337 shadow_ref.SetValue(NOT_CONST_INIT);
340 } 338 }
341 frame_->Pop(); // Value is no longer needed. 339 frame_->Pop(); // Value is no longer needed.
342 } 340 }
343 341
344 // Generate code to 'execute' declarations and initialize 342 // Generate code to 'execute' declarations and initialize functions
345 // functions (source elements). In case of an illegal 343 // (source elements). In case of an illegal redeclaration we need to
346 // redeclaration we need to handle that instead of processing the 344 // handle that instead of processing the declarations.
347 // declarations.
348 if (scope_->HasIllegalRedeclaration()) { 345 if (scope_->HasIllegalRedeclaration()) {
349 Comment cmnt(masm_, "[ illegal redeclarations"); 346 Comment cmnt(masm_, "[ illegal redeclarations");
350 scope_->VisitIllegalRedeclaration(this); 347 scope_->VisitIllegalRedeclaration(this);
351 } else { 348 } else {
352 Comment cmnt(masm_, "[ declarations"); 349 Comment cmnt(masm_, "[ declarations");
353 ProcessDeclarations(scope_->declarations()); 350 ProcessDeclarations(scope_->declarations());
354 // Bail out if a stack-overflow exception occurred when 351 // Bail out if a stack-overflow exception occurred when processing
355 // processing declarations. 352 // declarations.
356 if (HasStackOverflow()) return; 353 if (HasStackOverflow()) return;
357 } 354 }
358 355
359 if (FLAG_trace) { 356 if (FLAG_trace) {
360 __ CallRuntime(Runtime::kTraceEnter, 0); 357 __ CallRuntime(Runtime::kTraceEnter, 0);
361 // Ignore the return value. 358 // Ignore the return value.
362 } 359 }
363 CheckStack(); 360 CheckStack();
364 361
365 // Compile the body of the function in a vanilla state. Don't 362 // Compile the body of the function in a vanilla state. Don't
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
441 } 438 }
442 439
443 default: 440 default:
444 UNREACHABLE(); 441 UNREACHABLE();
445 return Operand(eax); 442 return Operand(eax);
446 } 443 }
447 } 444 }
448 445
449 446
450 // Loads a value on TOS. If it is a boolean value, the result may have been 447 // Loads a value on TOS. If it is a boolean value, the result may have been
451 // (partially) translated into branches, or it may have set the condition code 448 // (partially) translated into branches, or it may have set the condition
452 // register. If force_cc is set, the value is forced to set the condition code 449 // code register. If force_cc is set, the value is forced to set the
453 // register and no value is pushed. If the condition code register was set, 450 // condition code register and no value is pushed. If the condition code
454 // has_cc() is true and cc_reg_ contains the condition to test for 'true'. 451 // register was set, has_cc() is true and cc_reg_ contains the condition to
452 // test for 'true'.
455 void CodeGenerator::LoadCondition(Expression* x, 453 void CodeGenerator::LoadCondition(Expression* x,
456 TypeofState typeof_state, 454 TypeofState typeof_state,
457 Label* true_target, 455 Label* true_target,
458 Label* false_target, 456 Label* false_target,
459 bool force_cc) { 457 bool force_cc) {
460 ASSERT(!has_cc()); 458 ASSERT(!has_cc());
461 459
462 { CodeGenState new_state(this, typeof_state, true_target, false_target); 460 { CodeGenState new_state(this, typeof_state, true_target, false_target);
463 Visit(x); 461 Visit(x);
464 } 462 }
465 if (force_cc && !has_cc()) { 463 if (force_cc && !has_cc()) {
464 // Convert the TOS value to a boolean in the condition code register.
465 // Visiting an expression may possibly choose neither (a) to leave a
466 // value in the condition code register nor (b) to leave a value in TOS
467 // (eg, by compiling to only jumps to the targets). In that case the
468 // code generated by ToBoolean is wrong because it assumes the value of
469 // the expression in TOS. So long as there is always a value in TOS or
470 // the condition code register when control falls through to here (there
471 // is), the code generated by ToBoolean is dead and therefore safe.
466 ToBoolean(true_target, false_target); 472 ToBoolean(true_target, false_target);
467 } 473 }
468 ASSERT(has_cc() || !force_cc); 474 ASSERT(has_cc() || !force_cc);
469 } 475 }
470 476
471 477
472 void CodeGenerator::Load(Expression* x, TypeofState typeof_state) { 478 void CodeGenerator::Load(Expression* x, TypeofState typeof_state) {
473 Label true_target; 479 Label true_target;
474 Label false_target; 480 Label false_target;
475 LoadCondition(x, typeof_state, &true_target, &false_target, false); 481 LoadCondition(x, typeof_state, &true_target, &false_target, false);
476 482
477 if (has_cc()) { 483 if (has_cc()) {
478 // convert cc_reg_ into a bool 484 // convert cc_reg_ into a bool
479
480 Label loaded, materialize_true; 485 Label loaded, materialize_true;
481 __ j(cc_reg_, &materialize_true); 486 __ j(cc_reg_, &materialize_true);
482 frame_->Push(Immediate(Factory::false_value())); 487 frame_->Push(Immediate(Factory::false_value()));
483 __ jmp(&loaded); 488 __ jmp(&loaded);
484 __ bind(&materialize_true); 489 __ bind(&materialize_true);
485 frame_->Push(Immediate(Factory::true_value())); 490 frame_->Push(Immediate(Factory::true_value()));
486 __ bind(&loaded); 491 __ bind(&loaded);
487 cc_reg_ = no_condition; 492 cc_reg_ = no_condition;
488 } 493 }
489 494
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
656 ASSERT(kSmiTag == 0); 661 ASSERT(kSmiTag == 0);
657 __ test(eax, Operand(eax)); 662 __ test(eax, Operand(eax));
658 __ j(zero, false_target); 663 __ j(zero, false_target);
659 __ test(eax, Immediate(kSmiTagMask)); 664 __ test(eax, Immediate(kSmiTagMask));
660 __ j(zero, true_target); 665 __ j(zero, true_target);
661 666
662 // Call the stub for all other cases. 667 // Call the stub for all other cases.
663 frame_->Push(eax); // Undo the pop(eax) from above. 668 frame_->Push(eax); // Undo the pop(eax) from above.
664 ToBooleanStub stub; 669 ToBooleanStub stub;
665 __ CallStub(&stub); 670 __ CallStub(&stub);
666 // Convert result (eax) to condition code. 671 // Convert the result (eax) to condition code.
667 __ test(eax, Operand(eax)); 672 __ test(eax, Operand(eax));
668 673
669 ASSERT(not_equal == not_zero); 674 ASSERT(not_equal == not_zero);
670 cc_reg_ = not_equal; 675 cc_reg_ = not_equal;
671 } 676 }
672 677
673 678
674 class FloatingPointHelper : public AllStatic { 679 class FloatingPointHelper : public AllStatic {
675 public: 680 public:
676 // Code pattern for loading floating point values. Input values must 681 // Code pattern for loading floating point values. Input values must
(...skipping 1514 matching lines...) Expand 10 before | Expand all | Expand 10 after
2191 frame_->Pop(eax); 2196 frame_->Pop(eax);
2192 ExternalReference handler_address(Top::k_handler_address); 2197 ExternalReference handler_address(Top::k_handler_address);
2193 __ mov(edx, Operand::StaticVariable(handler_address)); 2198 __ mov(edx, Operand::StaticVariable(handler_address));
2194 const int kNextOffset = StackHandlerConstants::kNextOffset + 2199 const int kNextOffset = StackHandlerConstants::kNextOffset +
2195 StackHandlerConstants::kAddressDisplacement; 2200 StackHandlerConstants::kAddressDisplacement;
2196 __ lea(esp, Operand(edx, kNextOffset)); 2201 __ lea(esp, Operand(edx, kNextOffset));
2197 2202
2198 frame_->Pop(Operand::StaticVariable(handler_address)); 2203 frame_->Pop(Operand::StaticVariable(handler_address));
2199 frame_->Drop(StackHandlerConstants::kSize / kPointerSize - 1); 2204 frame_->Drop(StackHandlerConstants::kSize / kPointerSize - 1);
2200 // Next_sp popped. 2205 // Next_sp popped.
2201 // Preserve the TOS in a register across stack manipulation.
2202 frame_->Push(eax); 2206 frame_->Push(eax);
2203 2207
2204 // --- Finally block --- 2208 // --- Finally block ---
2205 __ bind(&finally_block); 2209 __ bind(&finally_block);
2206 2210
2207 // Push the state on the stack. 2211 // Push the state on the stack.
2208 frame_->Push(ecx); 2212 frame_->Push(ecx);
2209 2213
2210 // We keep two elements on the stack - the (possibly faked) result 2214 // We keep two elements on the stack - the (possibly faked) result
2211 // and the state - while evaluating the finally block. Record it, so 2215 // and the state - while evaluating the finally block. Record it, so
(...skipping 2937 matching lines...) Expand 10 before | Expand all | Expand 10 after
5149 5153
5150 // Slow-case: Go through the JavaScript implementation. 5154 // Slow-case: Go through the JavaScript implementation.
5151 __ bind(&slow); 5155 __ bind(&slow);
5152 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); 5156 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION);
5153 } 5157 }
5154 5158
5155 5159
5156 #undef __ 5160 #undef __
5157 5161
5158 } } // namespace v8::internal 5162 } } // namespace v8::internal
OLDNEW
« src/codegen-arm.cc ('K') | « src/codegen-arm.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698