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

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

Issue 7097011: Add tracing of the stack height to full code generator. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Final version Created 9 years, 4 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/full-codegen.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 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 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
159 if (locals_count == 1) { 159 if (locals_count == 1) {
160 __ push(Immediate(isolate()->factory()->undefined_value())); 160 __ push(Immediate(isolate()->factory()->undefined_value()));
161 } else if (locals_count > 1) { 161 } else if (locals_count > 1) {
162 __ mov(eax, Immediate(isolate()->factory()->undefined_value())); 162 __ mov(eax, Immediate(isolate()->factory()->undefined_value()));
163 for (int i = 0; i < locals_count; i++) { 163 for (int i = 0; i < locals_count; i++) {
164 __ push(eax); 164 __ push(eax);
165 } 165 }
166 } 166 }
167 } 167 }
168 168
169 set_stack_height(2 + scope()->num_stack_slots());
170 if (FLAG_verify_stack_height) {
171 verify_stack_height();
172 }
173
169 bool function_in_register = true; 174 bool function_in_register = true;
170 175
171 // Possibly allocate a local context. 176 // Possibly allocate a local context.
172 int heap_slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; 177 int heap_slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
173 if (heap_slots > 0) { 178 if (heap_slots > 0) {
174 Comment cmnt(masm_, "[ Allocate local context"); 179 Comment cmnt(masm_, "[ Allocate local context");
175 // Argument to NewContext is the function, which is still in edi. 180 // Argument to NewContext is the function, which is still in edi.
176 __ push(edi); 181 __ push(edi);
177 if (heap_slots <= FastNewContextStub::kMaximumSlots) { 182 if (heap_slots <= FastNewContextStub::kMaximumSlots) {
178 FastNewContextStub stub(heap_slots); 183 FastNewContextStub stub(heap_slots);
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
351 #ifdef ENABLE_DEBUGGER_SUPPORT 356 #ifdef ENABLE_DEBUGGER_SUPPORT
352 // Check that the size of the code used for returning is large enough 357 // Check that the size of the code used for returning is large enough
353 // for the debugger's requirements. 358 // for the debugger's requirements.
354 ASSERT(Assembler::kJSReturnSequenceLength <= 359 ASSERT(Assembler::kJSReturnSequenceLength <=
355 masm_->SizeOfCodeGeneratedSince(&check_exit_codesize)); 360 masm_->SizeOfCodeGeneratedSince(&check_exit_codesize));
356 #endif 361 #endif
357 } 362 }
358 } 363 }
359 364
360 365
366 void FullCodeGenerator::verify_stack_height() {
367 ASSERT(FLAG_verify_stack_height);
368 __ sub(Operand(ebp), Immediate(kPointerSize * stack_height()));
369 __ cmp(ebp, Operand(esp));
370 __ Assert(equal, "Full codegen stack height not as expected.");
371 __ add(Operand(ebp), Immediate(kPointerSize * stack_height()));
372 }
373
374
361 void FullCodeGenerator::EffectContext::Plug(Slot* slot) const { 375 void FullCodeGenerator::EffectContext::Plug(Slot* slot) const {
362 } 376 }
363 377
364 378
365 void FullCodeGenerator::AccumulatorValueContext::Plug(Slot* slot) const { 379 void FullCodeGenerator::AccumulatorValueContext::Plug(Slot* slot) const {
366 MemOperand slot_operand = codegen()->EmitSlotSearch(slot, result_register()); 380 MemOperand slot_operand = codegen()->EmitSlotSearch(slot, result_register());
367 __ mov(result_register(), slot_operand); 381 __ mov(result_register(), slot_operand);
368 } 382 }
369 383
370 384
371 void FullCodeGenerator::StackValueContext::Plug(Slot* slot) const { 385 void FullCodeGenerator::StackValueContext::Plug(Slot* slot) const {
372 MemOperand slot_operand = codegen()->EmitSlotSearch(slot, result_register()); 386 MemOperand slot_operand = codegen()->EmitSlotSearch(slot, result_register());
373 // Memory operands can be pushed directly. 387 // Memory operands can be pushed directly.
374 __ push(slot_operand); 388 __ push(slot_operand);
389 codegen()->increment_stack_height();
375 } 390 }
376 391
377 392
378 void FullCodeGenerator::TestContext::Plug(Slot* slot) const { 393 void FullCodeGenerator::TestContext::Plug(Slot* slot) const {
379 // For simplicity we always test the accumulator register. 394 // For simplicity we always test the accumulator register.
380 codegen()->Move(result_register(), slot); 395 codegen()->Move(result_register(), slot);
381 codegen()->PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL); 396 codegen()->PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL);
382 codegen()->DoTest(this); 397 codegen()->DoTest(this);
383 } 398 }
384 399
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
418 } 433 }
419 } 434 }
420 435
421 436
422 void FullCodeGenerator::StackValueContext::Plug(Handle<Object> lit) const { 437 void FullCodeGenerator::StackValueContext::Plug(Handle<Object> lit) const {
423 if (lit->IsSmi()) { 438 if (lit->IsSmi()) {
424 __ SafePush(Immediate(lit)); 439 __ SafePush(Immediate(lit));
425 } else { 440 } else {
426 __ push(Immediate(lit)); 441 __ push(Immediate(lit));
427 } 442 }
443 codegen()->increment_stack_height();
428 } 444 }
429 445
430 446
431 void FullCodeGenerator::TestContext::Plug(Handle<Object> lit) const { 447 void FullCodeGenerator::TestContext::Plug(Handle<Object> lit) const {
432 codegen()->PrepareForBailoutBeforeSplit(TOS_REG, 448 codegen()->PrepareForBailoutBeforeSplit(TOS_REG,
433 true, 449 true,
434 true_label_, 450 true_label_,
435 false_label_); 451 false_label_);
436 ASSERT(!lit->IsUndetectableObject()); // There are no undetectable literals. 452 ASSERT(!lit->IsUndetectableObject()); // There are no undetectable literals.
437 if (lit->IsUndefined() || lit->IsNull() || lit->IsFalse()) { 453 if (lit->IsUndefined() || lit->IsNull() || lit->IsFalse()) {
(...skipping 17 matching lines...) Expand all
455 __ mov(result_register(), lit); 471 __ mov(result_register(), lit);
456 codegen()->DoTest(this); 472 codegen()->DoTest(this);
457 } 473 }
458 } 474 }
459 475
460 476
461 void FullCodeGenerator::EffectContext::DropAndPlug(int count, 477 void FullCodeGenerator::EffectContext::DropAndPlug(int count,
462 Register reg) const { 478 Register reg) const {
463 ASSERT(count > 0); 479 ASSERT(count > 0);
464 __ Drop(count); 480 __ Drop(count);
481 codegen()->decrement_stack_height(count);
465 } 482 }
466 483
467 484
468 void FullCodeGenerator::AccumulatorValueContext::DropAndPlug( 485 void FullCodeGenerator::AccumulatorValueContext::DropAndPlug(
469 int count, 486 int count,
470 Register reg) const { 487 Register reg) const {
471 ASSERT(count > 0); 488 ASSERT(count > 0);
472 __ Drop(count); 489 __ Drop(count);
473 __ Move(result_register(), reg); 490 __ Move(result_register(), reg);
491 codegen()->decrement_stack_height(count);
474 } 492 }
475 493
476 494
477 void FullCodeGenerator::StackValueContext::DropAndPlug(int count, 495 void FullCodeGenerator::StackValueContext::DropAndPlug(int count,
478 Register reg) const { 496 Register reg) const {
479 ASSERT(count > 0); 497 ASSERT(count > 0);
480 if (count > 1) __ Drop(count - 1); 498 if (count > 1) __ Drop(count - 1);
481 __ mov(Operand(esp, 0), reg); 499 __ mov(Operand(esp, 0), reg);
500 codegen()->decrement_stack_height(count - 1);
482 } 501 }
483 502
484 503
485 void FullCodeGenerator::TestContext::DropAndPlug(int count, 504 void FullCodeGenerator::TestContext::DropAndPlug(int count,
486 Register reg) const { 505 Register reg) const {
487 ASSERT(count > 0); 506 ASSERT(count > 0);
488 // For simplicity we always test the accumulator register. 507 // For simplicity we always test the accumulator register.
489 __ Drop(count); 508 __ Drop(count);
490 __ Move(result_register(), reg); 509 __ Move(result_register(), reg);
491 codegen()->PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL); 510 codegen()->PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL);
492 codegen()->DoTest(this); 511 codegen()->DoTest(this);
512 codegen()->decrement_stack_height(count);
493 } 513 }
494 514
495 515
496 void FullCodeGenerator::EffectContext::Plug(Label* materialize_true, 516 void FullCodeGenerator::EffectContext::Plug(Label* materialize_true,
497 Label* materialize_false) const { 517 Label* materialize_false) const {
498 ASSERT(materialize_true == materialize_false); 518 ASSERT(materialize_true == materialize_false);
499 __ bind(materialize_true); 519 __ bind(materialize_true);
500 } 520 }
501 521
502 522
(...skipping 13 matching lines...) Expand all
516 void FullCodeGenerator::StackValueContext::Plug( 536 void FullCodeGenerator::StackValueContext::Plug(
517 Label* materialize_true, 537 Label* materialize_true,
518 Label* materialize_false) const { 538 Label* materialize_false) const {
519 Label done; 539 Label done;
520 __ bind(materialize_true); 540 __ bind(materialize_true);
521 __ push(Immediate(isolate()->factory()->true_value())); 541 __ push(Immediate(isolate()->factory()->true_value()));
522 __ jmp(&done, Label::kNear); 542 __ jmp(&done, Label::kNear);
523 __ bind(materialize_false); 543 __ bind(materialize_false);
524 __ push(Immediate(isolate()->factory()->false_value())); 544 __ push(Immediate(isolate()->factory()->false_value()));
525 __ bind(&done); 545 __ bind(&done);
546 codegen()->increment_stack_height();
526 } 547 }
527 548
528 549
529 void FullCodeGenerator::TestContext::Plug(Label* materialize_true, 550 void FullCodeGenerator::TestContext::Plug(Label* materialize_true,
530 Label* materialize_false) const { 551 Label* materialize_false) const {
531 ASSERT(materialize_true == true_label_); 552 ASSERT(materialize_true == true_label_);
532 ASSERT(materialize_false == false_label_); 553 ASSERT(materialize_false == false_label_);
533 } 554 }
534 555
535 556
536 void FullCodeGenerator::EffectContext::Plug(bool flag) const { 557 void FullCodeGenerator::EffectContext::Plug(bool flag) const {
537 } 558 }
538 559
539 560
540 void FullCodeGenerator::AccumulatorValueContext::Plug(bool flag) const { 561 void FullCodeGenerator::AccumulatorValueContext::Plug(bool flag) const {
541 Handle<Object> value = flag 562 Handle<Object> value = flag
542 ? isolate()->factory()->true_value() 563 ? isolate()->factory()->true_value()
543 : isolate()->factory()->false_value(); 564 : isolate()->factory()->false_value();
544 __ mov(result_register(), value); 565 __ mov(result_register(), value);
545 } 566 }
546 567
547 568
548 void FullCodeGenerator::StackValueContext::Plug(bool flag) const { 569 void FullCodeGenerator::StackValueContext::Plug(bool flag) const {
549 Handle<Object> value = flag 570 Handle<Object> value = flag
550 ? isolate()->factory()->true_value() 571 ? isolate()->factory()->true_value()
551 : isolate()->factory()->false_value(); 572 : isolate()->factory()->false_value();
552 __ push(Immediate(value)); 573 __ push(Immediate(value));
574 codegen()->increment_stack_height();
553 } 575 }
554 576
555 577
556 void FullCodeGenerator::TestContext::Plug(bool flag) const { 578 void FullCodeGenerator::TestContext::Plug(bool flag) const {
557 codegen()->PrepareForBailoutBeforeSplit(TOS_REG, 579 codegen()->PrepareForBailoutBeforeSplit(TOS_REG,
558 true, 580 true,
559 true_label_, 581 true_label_,
560 false_label_); 582 false_label_);
561 if (flag) { 583 if (flag) {
562 if (true_label_ != fall_through_) __ jmp(true_label_); 584 if (true_label_ != fall_through_) __ jmp(true_label_);
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
715 __ push(esi); 737 __ push(esi);
716 __ push(Immediate(variable->name())); 738 __ push(Immediate(variable->name()));
717 // Declaration nodes are always introduced in one of two modes. 739 // Declaration nodes are always introduced in one of two modes.
718 ASSERT(mode == Variable::VAR || mode == Variable::CONST); 740 ASSERT(mode == Variable::VAR || mode == Variable::CONST);
719 PropertyAttributes attr = (mode == Variable::VAR) ? NONE : READ_ONLY; 741 PropertyAttributes attr = (mode == Variable::VAR) ? NONE : READ_ONLY;
720 __ push(Immediate(Smi::FromInt(attr))); 742 __ push(Immediate(Smi::FromInt(attr)));
721 // Push initial value, if any. 743 // Push initial value, if any.
722 // Note: For variables we must not push an initial value (such as 744 // Note: For variables we must not push an initial value (such as
723 // 'undefined') because we may have a (legal) redeclaration and we 745 // 'undefined') because we may have a (legal) redeclaration and we
724 // must not destroy the current value. 746 // must not destroy the current value.
747 increment_stack_height(3);
725 if (mode == Variable::CONST) { 748 if (mode == Variable::CONST) {
726 __ push(Immediate(isolate()->factory()->the_hole_value())); 749 __ push(Immediate(isolate()->factory()->the_hole_value()));
750 increment_stack_height();
727 } else if (function != NULL) { 751 } else if (function != NULL) {
728 VisitForStackValue(function); 752 VisitForStackValue(function);
729 } else { 753 } else {
730 __ push(Immediate(Smi::FromInt(0))); // No initial value! 754 __ push(Immediate(Smi::FromInt(0))); // No initial value!
755 increment_stack_height();
731 } 756 }
732 __ CallRuntime(Runtime::kDeclareContextSlot, 4); 757 __ CallRuntime(Runtime::kDeclareContextSlot, 4);
758 decrement_stack_height(4);
733 break; 759 break;
734 } 760 }
735 } 761 }
736 762
737 } else if (prop != NULL) { 763 } else if (prop != NULL) {
738 // A const declaration aliasing a parameter is an illegal redeclaration. 764 // A const declaration aliasing a parameter is an illegal redeclaration.
739 ASSERT(mode != Variable::CONST); 765 ASSERT(mode != Variable::CONST);
740 if (function != NULL) { 766 if (function != NULL) {
741 // We are declaring a function that rewrites to a property. 767 // We are declaring a function that rewrites to a property.
742 // Use (keyed) IC to set the initial value. We cannot visit the 768 // Use (keyed) IC to set the initial value. We cannot visit the
743 // rewrite because it's shared and we risk recording duplicate AST 769 // rewrite because it's shared and we risk recording duplicate AST
744 // IDs for bailouts from optimized code. 770 // IDs for bailouts from optimized code.
745 ASSERT(prop->obj()->AsVariableProxy() != NULL); 771 ASSERT(prop->obj()->AsVariableProxy() != NULL);
746 { AccumulatorValueContext for_object(this); 772 { AccumulatorValueContext for_object(this);
747 EmitVariableLoad(prop->obj()->AsVariableProxy()); 773 EmitVariableLoad(prop->obj()->AsVariableProxy());
748 } 774 }
749 775
750 __ push(eax); 776 __ push(eax);
777 increment_stack_height();
751 VisitForAccumulatorValue(function); 778 VisitForAccumulatorValue(function);
752 __ pop(edx); 779 __ pop(edx);
780 decrement_stack_height();
753 781
754 ASSERT(prop->key()->AsLiteral() != NULL && 782 ASSERT(prop->key()->AsLiteral() != NULL &&
755 prop->key()->AsLiteral()->handle()->IsSmi()); 783 prop->key()->AsLiteral()->handle()->IsSmi());
756 __ SafeSet(ecx, Immediate(prop->key()->AsLiteral()->handle())); 784 __ SafeSet(ecx, Immediate(prop->key()->AsLiteral()->handle()));
757 785
758 Handle<Code> ic = is_strict_mode() 786 Handle<Code> ic = is_strict_mode()
759 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 787 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
760 : isolate()->builtins()->KeyedStoreIC_Initialize(); 788 : isolate()->builtins()->KeyedStoreIC_Initialize();
761 __ call(ic); 789 __ call(ic);
762 } 790 }
(...skipping 15 matching lines...) Expand all
778 __ CallRuntime(Runtime::kDeclareGlobals, 4); 806 __ CallRuntime(Runtime::kDeclareGlobals, 4);
779 // Return value is ignored. 807 // Return value is ignored.
780 } 808 }
781 809
782 810
783 void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { 811 void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
784 Comment cmnt(masm_, "[ SwitchStatement"); 812 Comment cmnt(masm_, "[ SwitchStatement");
785 Breakable nested_statement(this, stmt); 813 Breakable nested_statement(this, stmt);
786 SetStatementPosition(stmt); 814 SetStatementPosition(stmt);
787 815
816 int switch_clause_stack_height = stack_height();
788 // Keep the switch value on the stack until a case matches. 817 // Keep the switch value on the stack until a case matches.
789 VisitForStackValue(stmt->tag()); 818 VisitForStackValue(stmt->tag());
790 PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS); 819 PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS);
791 820
792 ZoneList<CaseClause*>* clauses = stmt->cases(); 821 ZoneList<CaseClause*>* clauses = stmt->cases();
793 CaseClause* default_clause = NULL; // Can occur anywhere in the list. 822 CaseClause* default_clause = NULL; // Can occur anywhere in the list.
794 823
795 Label next_test; // Recycled for each test. 824 Label next_test; // Recycled for each test.
796 // Compile all the tests with branches to their bodies. 825 // Compile all the tests with branches to their bodies.
797 for (int i = 0; i < clauses->length(); i++) { 826 for (int i = 0; i < clauses->length(); i++) {
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
842 // Discard the test value and jump to the default if present, otherwise to 871 // Discard the test value and jump to the default if present, otherwise to
843 // the end of the statement. 872 // the end of the statement.
844 __ bind(&next_test); 873 __ bind(&next_test);
845 __ Drop(1); // Switch value is no longer needed. 874 __ Drop(1); // Switch value is no longer needed.
846 if (default_clause == NULL) { 875 if (default_clause == NULL) {
847 __ jmp(nested_statement.break_target()); 876 __ jmp(nested_statement.break_target());
848 } else { 877 } else {
849 __ jmp(default_clause->body_target()); 878 __ jmp(default_clause->body_target());
850 } 879 }
851 880
881 set_stack_height(switch_clause_stack_height);
852 // Compile all the case bodies. 882 // Compile all the case bodies.
853 for (int i = 0; i < clauses->length(); i++) { 883 for (int i = 0; i < clauses->length(); i++) {
854 Comment cmnt(masm_, "[ Case body"); 884 Comment cmnt(masm_, "[ Case body");
855 CaseClause* clause = clauses->at(i); 885 CaseClause* clause = clauses->at(i);
856 __ bind(clause->body_target()); 886 __ bind(clause->body_target());
857 PrepareForBailoutForId(clause->EntryId(), NO_REGISTERS); 887 PrepareForBailoutForId(clause->EntryId(), NO_REGISTERS);
858 VisitStatements(clause->statements()); 888 VisitStatements(clause->statements());
859 } 889 }
860 890
861 __ bind(nested_statement.break_target()); 891 __ bind(nested_statement.break_target());
(...skipping 21 matching lines...) Expand all
883 // Convert the object to a JS object. 913 // Convert the object to a JS object.
884 Label convert, done_convert; 914 Label convert, done_convert;
885 __ JumpIfSmi(eax, &convert, Label::kNear); 915 __ JumpIfSmi(eax, &convert, Label::kNear);
886 __ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, ecx); 916 __ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, ecx);
887 __ j(above_equal, &done_convert, Label::kNear); 917 __ j(above_equal, &done_convert, Label::kNear);
888 __ bind(&convert); 918 __ bind(&convert);
889 __ push(eax); 919 __ push(eax);
890 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION); 920 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
891 __ bind(&done_convert); 921 __ bind(&done_convert);
892 __ push(eax); 922 __ push(eax);
923 increment_stack_height();
893 924
894 // Check cache validity in generated code. This is a fast case for 925 // Check cache validity in generated code. This is a fast case for
895 // the JSObject::IsSimpleEnum cache validity checks. If we cannot 926 // the JSObject::IsSimpleEnum cache validity checks. If we cannot
896 // guarantee cache validity, call the runtime system to check cache 927 // guarantee cache validity, call the runtime system to check cache
897 // validity or get the property names in a fixed array. 928 // validity or get the property names in a fixed array.
898 Label next, call_runtime; 929 Label next, call_runtime;
899 __ mov(ecx, eax); 930 __ mov(ecx, eax);
900 __ bind(&next); 931 __ bind(&next);
901 932
902 // Check that there are no elements. Register ecx contains the 933 // Check that there are no elements. Register ecx contains the
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
966 __ jmp(&loop); 997 __ jmp(&loop);
967 998
968 // We got a fixed array in register eax. Iterate through that. 999 // We got a fixed array in register eax. Iterate through that.
969 __ bind(&fixed_array); 1000 __ bind(&fixed_array);
970 __ push(Immediate(Smi::FromInt(0))); // Map (0) - force slow check. 1001 __ push(Immediate(Smi::FromInt(0))); // Map (0) - force slow check.
971 __ push(eax); 1002 __ push(eax);
972 __ mov(eax, FieldOperand(eax, FixedArray::kLengthOffset)); 1003 __ mov(eax, FieldOperand(eax, FixedArray::kLengthOffset));
973 __ push(eax); // Fixed array length (as smi). 1004 __ push(eax); // Fixed array length (as smi).
974 __ push(Immediate(Smi::FromInt(0))); // Initial index. 1005 __ push(Immediate(Smi::FromInt(0))); // Initial index.
975 1006
1007 increment_stack_height(4);
976 // Generate code for doing the condition check. 1008 // Generate code for doing the condition check.
977 __ bind(&loop); 1009 __ bind(&loop);
978 __ mov(eax, Operand(esp, 0 * kPointerSize)); // Get the current index. 1010 __ mov(eax, Operand(esp, 0 * kPointerSize)); // Get the current index.
979 __ cmp(eax, Operand(esp, 1 * kPointerSize)); // Compare to the array length. 1011 __ cmp(eax, Operand(esp, 1 * kPointerSize)); // Compare to the array length.
980 __ j(above_equal, loop_statement.break_target()); 1012 __ j(above_equal, loop_statement.break_target());
981 1013
982 // Get the current entry of the array into register ebx. 1014 // Get the current entry of the array into register ebx.
983 __ mov(ebx, Operand(esp, 2 * kPointerSize)); 1015 __ mov(ebx, Operand(esp, 2 * kPointerSize));
984 __ mov(ebx, FieldOperand(ebx, eax, times_2, FixedArray::kHeaderSize)); 1016 __ mov(ebx, FieldOperand(ebx, eax, times_2, FixedArray::kHeaderSize));
985 1017
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1021 __ bind(loop_statement.continue_target()); 1053 __ bind(loop_statement.continue_target());
1022 __ add(Operand(esp, 0 * kPointerSize), Immediate(Smi::FromInt(1))); 1054 __ add(Operand(esp, 0 * kPointerSize), Immediate(Smi::FromInt(1)));
1023 1055
1024 EmitStackCheck(stmt); 1056 EmitStackCheck(stmt);
1025 __ jmp(&loop); 1057 __ jmp(&loop);
1026 1058
1027 // Remove the pointers stored on the stack. 1059 // Remove the pointers stored on the stack.
1028 __ bind(loop_statement.break_target()); 1060 __ bind(loop_statement.break_target());
1029 __ add(Operand(esp), Immediate(5 * kPointerSize)); 1061 __ add(Operand(esp), Immediate(5 * kPointerSize));
1030 1062
1063 decrement_stack_height(5);
1031 // Exit and decrement the loop depth. 1064 // Exit and decrement the loop depth.
1032 __ bind(&exit); 1065 __ bind(&exit);
1033 decrement_loop_depth(); 1066 decrement_loop_depth();
1034 } 1067 }
1035 1068
1036 1069
1037 void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info, 1070 void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info,
1038 bool pretenure) { 1071 bool pretenure) {
1039 // Use the fast case closure allocation code that allocates in new 1072 // Use the fast case closure allocation code that allocates in new
1040 // space for nested functions that don't need literals cloning. If 1073 // space for nested functions that don't need literals cloning. If
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after
1356 1389
1357 for (int i = 0; i < expr->properties()->length(); i++) { 1390 for (int i = 0; i < expr->properties()->length(); i++) {
1358 ObjectLiteral::Property* property = expr->properties()->at(i); 1391 ObjectLiteral::Property* property = expr->properties()->at(i);
1359 if (property->IsCompileTimeValue()) continue; 1392 if (property->IsCompileTimeValue()) continue;
1360 1393
1361 Literal* key = property->key(); 1394 Literal* key = property->key();
1362 Expression* value = property->value(); 1395 Expression* value = property->value();
1363 if (!result_saved) { 1396 if (!result_saved) {
1364 __ push(eax); // Save result on the stack 1397 __ push(eax); // Save result on the stack
1365 result_saved = true; 1398 result_saved = true;
1399 increment_stack_height();
1366 } 1400 }
1367 switch (property->kind()) { 1401 switch (property->kind()) {
1368 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1402 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1369 ASSERT(!CompileTimeValue::IsCompileTimeValue(value)); 1403 ASSERT(!CompileTimeValue::IsCompileTimeValue(value));
1370 // Fall through. 1404 // Fall through.
1371 case ObjectLiteral::Property::COMPUTED: 1405 case ObjectLiteral::Property::COMPUTED:
1372 if (key->handle()->IsSymbol()) { 1406 if (key->handle()->IsSymbol()) {
1373 if (property->emit_store()) { 1407 if (property->emit_store()) {
1374 VisitForAccumulatorValue(value); 1408 VisitForAccumulatorValue(value);
1375 __ mov(ecx, Immediate(key->handle())); 1409 __ mov(ecx, Immediate(key->handle()));
1376 __ mov(edx, Operand(esp, 0)); 1410 __ mov(edx, Operand(esp, 0));
1377 Handle<Code> ic = is_strict_mode() 1411 Handle<Code> ic = is_strict_mode()
1378 ? isolate()->builtins()->StoreIC_Initialize_Strict() 1412 ? isolate()->builtins()->StoreIC_Initialize_Strict()
1379 : isolate()->builtins()->StoreIC_Initialize(); 1413 : isolate()->builtins()->StoreIC_Initialize();
1380 __ call(ic, RelocInfo::CODE_TARGET, key->id()); 1414 __ call(ic, RelocInfo::CODE_TARGET, key->id());
1381 PrepareForBailoutForId(key->id(), NO_REGISTERS); 1415 PrepareForBailoutForId(key->id(), NO_REGISTERS);
1382 } else { 1416 } else {
1383 VisitForEffect(value); 1417 VisitForEffect(value);
1384 } 1418 }
1385 break; 1419 break;
1386 } 1420 }
1387 // Fall through. 1421 // Fall through.
1388 case ObjectLiteral::Property::PROTOTYPE: 1422 case ObjectLiteral::Property::PROTOTYPE:
1389 __ push(Operand(esp, 0)); // Duplicate receiver. 1423 __ push(Operand(esp, 0)); // Duplicate receiver.
1424 increment_stack_height();
1390 VisitForStackValue(key); 1425 VisitForStackValue(key);
1391 VisitForStackValue(value); 1426 VisitForStackValue(value);
1392 if (property->emit_store()) { 1427 if (property->emit_store()) {
1393 __ push(Immediate(Smi::FromInt(NONE))); // PropertyAttributes 1428 __ push(Immediate(Smi::FromInt(NONE))); // PropertyAttributes
1394 __ CallRuntime(Runtime::kSetProperty, 4); 1429 __ CallRuntime(Runtime::kSetProperty, 4);
1395 } else { 1430 } else {
1396 __ Drop(3); 1431 __ Drop(3);
1397 } 1432 }
1433 decrement_stack_height(3);
1398 break; 1434 break;
1399 case ObjectLiteral::Property::SETTER: 1435 case ObjectLiteral::Property::SETTER:
1400 case ObjectLiteral::Property::GETTER: 1436 case ObjectLiteral::Property::GETTER:
1401 __ push(Operand(esp, 0)); // Duplicate receiver. 1437 __ push(Operand(esp, 0)); // Duplicate receiver.
1438 increment_stack_height();
1402 VisitForStackValue(key); 1439 VisitForStackValue(key);
1403 __ push(Immediate(property->kind() == ObjectLiteral::Property::SETTER ? 1440 __ push(Immediate(property->kind() == ObjectLiteral::Property::SETTER ?
1404 Smi::FromInt(1) : 1441 Smi::FromInt(1) :
1405 Smi::FromInt(0))); 1442 Smi::FromInt(0)));
1443 increment_stack_height();
1406 VisitForStackValue(value); 1444 VisitForStackValue(value);
1407 __ CallRuntime(Runtime::kDefineAccessor, 4); 1445 __ CallRuntime(Runtime::kDefineAccessor, 4);
1446 decrement_stack_height(4);
1408 break; 1447 break;
1409 default: UNREACHABLE(); 1448 default: UNREACHABLE();
1410 } 1449 }
1411 } 1450 }
1412 1451
1413 if (expr->has_function()) { 1452 if (expr->has_function()) {
1414 ASSERT(result_saved); 1453 ASSERT(result_saved);
1415 __ push(Operand(esp, 0)); 1454 __ push(Operand(esp, 0));
1416 __ CallRuntime(Runtime::kToFastProperties, 1); 1455 __ CallRuntime(Runtime::kToFastProperties, 1);
1417 } 1456 }
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1460 // If the subexpression is a literal or a simple materialized literal it 1499 // If the subexpression is a literal or a simple materialized literal it
1461 // is already set in the cloned array. 1500 // is already set in the cloned array.
1462 if (subexpr->AsLiteral() != NULL || 1501 if (subexpr->AsLiteral() != NULL ||
1463 CompileTimeValue::IsCompileTimeValue(subexpr)) { 1502 CompileTimeValue::IsCompileTimeValue(subexpr)) {
1464 continue; 1503 continue;
1465 } 1504 }
1466 1505
1467 if (!result_saved) { 1506 if (!result_saved) {
1468 __ push(eax); 1507 __ push(eax);
1469 result_saved = true; 1508 result_saved = true;
1509 increment_stack_height();
1470 } 1510 }
1471 VisitForAccumulatorValue(subexpr); 1511 VisitForAccumulatorValue(subexpr);
1472 1512
1473 // Store the subexpression value in the array's elements. 1513 // Store the subexpression value in the array's elements.
1474 __ mov(ebx, Operand(esp, 0)); // Copy of array literal. 1514 __ mov(ebx, Operand(esp, 0)); // Copy of array literal.
1475 __ mov(ebx, FieldOperand(ebx, JSObject::kElementsOffset)); 1515 __ mov(ebx, FieldOperand(ebx, JSObject::kElementsOffset));
1476 int offset = FixedArray::kHeaderSize + (i * kPointerSize); 1516 int offset = FixedArray::kHeaderSize + (i * kPointerSize);
1477 __ mov(FieldOperand(ebx, offset), result_register()); 1517 __ mov(FieldOperand(ebx, offset), result_register());
1478 1518
1479 // Update the write barrier for the array store. 1519 // Update the write barrier for the array store.
1480 __ RecordWrite(ebx, offset, result_register(), ecx); 1520 __ RecordWrite(ebx, offset, result_register(), ecx);
1481 1521
1482 PrepareForBailoutForId(expr->GetIdForElement(i), NO_REGISTERS); 1522 PrepareForBailoutForId(expr->GetIdForElement(i), NO_REGISTERS);
1483 } 1523 }
1484 1524
1485 if (result_saved) { 1525 if (result_saved) {
1486 context()->PlugTOS(); 1526 context()->PlugTOS();
1487 } else { 1527 } else {
1488 context()->Plug(eax); 1528 context()->Plug(eax);
1489 } 1529 }
1490 } 1530 }
1491 1531
1492 1532
1493 void FullCodeGenerator::VisitAssignment(Assignment* expr) { 1533 void FullCodeGenerator::VisitAssignment(Assignment* expr) {
1494 Comment cmnt(masm_, "[ Assignment"); 1534 Comment cmnt(masm_, "[ Assignment");
1495 // Invalid left-hand sides are rewritten to have a 'throw ReferenceError' 1535 // Invalid left-hand sides are rewritten to have a 'throw ReferenceError'
1496 // on the left-hand side. 1536 // on the left-hand side.
1497 if (!expr->target()->IsValidLeftHandSide()) { 1537 if (!expr->target()->IsValidLeftHandSide()) {
1498 VisitForEffect(expr->target()); 1538 ASSERT(expr->target()->AsThrow() != NULL);
1539 VisitInCurrentContext(expr->target()); // Throw does not plug the context
1540 context()->Plug(eax);
1499 return; 1541 return;
1500 } 1542 }
1501 1543
1502 // Left-hand side can only be a property, a global or a (parameter or local) 1544 // Left-hand side can only be a property, a global or a (parameter or local)
1503 // slot. 1545 // slot.
1504 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; 1546 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
1505 LhsKind assign_type = VARIABLE; 1547 LhsKind assign_type = VARIABLE;
1506 Property* property = expr->target()->AsProperty(); 1548 Property* property = expr->target()->AsProperty();
1507 if (property != NULL) { 1549 if (property != NULL) {
1508 assign_type = (property->key()->IsPropertyName()) 1550 assign_type = (property->key()->IsPropertyName())
1509 ? NAMED_PROPERTY 1551 ? NAMED_PROPERTY
1510 : KEYED_PROPERTY; 1552 : KEYED_PROPERTY;
1511 } 1553 }
1512 1554
1513 // Evaluate LHS expression. 1555 // Evaluate LHS expression.
1514 switch (assign_type) { 1556 switch (assign_type) {
1515 case VARIABLE: 1557 case VARIABLE:
1516 // Nothing to do here. 1558 // Nothing to do here.
1517 break; 1559 break;
1518 case NAMED_PROPERTY: 1560 case NAMED_PROPERTY:
1519 if (expr->is_compound()) { 1561 if (expr->is_compound()) {
1520 // We need the receiver both on the stack and in the accumulator. 1562 // We need the receiver both on the stack and in the accumulator.
1521 VisitForAccumulatorValue(property->obj()); 1563 VisitForAccumulatorValue(property->obj());
1522 __ push(result_register()); 1564 __ push(result_register());
1565 increment_stack_height();
1523 } else { 1566 } else {
1524 VisitForStackValue(property->obj()); 1567 VisitForStackValue(property->obj());
1525 } 1568 }
1526 break; 1569 break;
1527 case KEYED_PROPERTY: { 1570 case KEYED_PROPERTY: {
1528 if (expr->is_compound()) { 1571 if (expr->is_compound()) {
1529 VisitForStackValue(property->obj()); 1572 VisitForStackValue(property->obj());
1530 VisitForAccumulatorValue(property->key()); 1573 VisitForAccumulatorValue(property->key());
1531 __ mov(edx, Operand(esp, 0)); 1574 __ mov(edx, Operand(esp, 0));
1532 __ push(eax); 1575 __ push(eax);
1576 increment_stack_height();
1533 } else { 1577 } else {
1534 VisitForStackValue(property->obj()); 1578 VisitForStackValue(property->obj());
1535 VisitForStackValue(property->key()); 1579 VisitForStackValue(property->key());
1536 } 1580 }
1537 break; 1581 break;
1538 } 1582 }
1539 } 1583 }
1540 1584
1541 // For compound assignments we need another deoptimization point after the 1585 // For compound assignments we need another deoptimization point after the
1542 // variable/property load. 1586 // variable/property load.
1543 if (expr->is_compound()) { 1587 if (expr->is_compound()) {
1544 { AccumulatorValueContext context(this); 1588 AccumulatorValueContext result_context(this);
1589 { AccumulatorValueContext left_operand_context(this);
1545 switch (assign_type) { 1590 switch (assign_type) {
1546 case VARIABLE: 1591 case VARIABLE:
1547 EmitVariableLoad(expr->target()->AsVariableProxy()); 1592 EmitVariableLoad(expr->target()->AsVariableProxy());
1548 PrepareForBailout(expr->target(), TOS_REG); 1593 PrepareForBailout(expr->target(), TOS_REG);
1549 break; 1594 break;
1550 case NAMED_PROPERTY: 1595 case NAMED_PROPERTY:
1551 EmitNamedPropertyLoad(property); 1596 EmitNamedPropertyLoad(property);
1552 PrepareForBailoutForId(expr->CompoundLoadId(), TOS_REG); 1597 PrepareForBailoutForId(expr->CompoundLoadId(), TOS_REG);
1553 break; 1598 break;
1554 case KEYED_PROPERTY: 1599 case KEYED_PROPERTY:
1555 EmitKeyedPropertyLoad(property); 1600 EmitKeyedPropertyLoad(property);
1556 PrepareForBailoutForId(expr->CompoundLoadId(), TOS_REG); 1601 PrepareForBailoutForId(expr->CompoundLoadId(), TOS_REG);
1557 break; 1602 break;
1558 } 1603 }
1559 } 1604 }
1560 1605
1561 Token::Value op = expr->binary_op(); 1606 Token::Value op = expr->binary_op();
1562 __ push(eax); // Left operand goes on the stack. 1607 __ push(eax); // Left operand goes on the stack.
1608 increment_stack_height();
1563 VisitForAccumulatorValue(expr->value()); 1609 VisitForAccumulatorValue(expr->value());
1564 1610
1565 OverwriteMode mode = expr->value()->ResultOverwriteAllowed() 1611 OverwriteMode mode = expr->value()->ResultOverwriteAllowed()
1566 ? OVERWRITE_RIGHT 1612 ? OVERWRITE_RIGHT
1567 : NO_OVERWRITE; 1613 : NO_OVERWRITE;
1568 SetSourcePosition(expr->position() + 1); 1614 SetSourcePosition(expr->position() + 1);
1569 AccumulatorValueContext context(this);
1570 if (ShouldInlineSmiCase(op)) { 1615 if (ShouldInlineSmiCase(op)) {
1571 EmitInlineSmiBinaryOp(expr->binary_operation(), 1616 EmitInlineSmiBinaryOp(expr->binary_operation(),
1572 op, 1617 op,
1573 mode, 1618 mode,
1574 expr->target(), 1619 expr->target(),
1575 expr->value()); 1620 expr->value());
1576 } else { 1621 } else {
1577 EmitBinaryOp(expr->binary_operation(), op, mode); 1622 EmitBinaryOp(expr->binary_operation(), op, mode);
1578 } 1623 }
1579 1624
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1623 1668
1624 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, 1669 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
1625 Token::Value op, 1670 Token::Value op,
1626 OverwriteMode mode, 1671 OverwriteMode mode,
1627 Expression* left, 1672 Expression* left,
1628 Expression* right) { 1673 Expression* right) {
1629 // Do combined smi check of the operands. Left operand is on the 1674 // Do combined smi check of the operands. Left operand is on the
1630 // stack. Right operand is in eax. 1675 // stack. Right operand is in eax.
1631 Label smi_case, done, stub_call; 1676 Label smi_case, done, stub_call;
1632 __ pop(edx); 1677 __ pop(edx);
1678 decrement_stack_height();
1633 __ mov(ecx, eax); 1679 __ mov(ecx, eax);
1634 __ or_(eax, Operand(edx)); 1680 __ or_(eax, Operand(edx));
1635 JumpPatchSite patch_site(masm_); 1681 JumpPatchSite patch_site(masm_);
1636 patch_site.EmitJumpIfSmi(eax, &smi_case, Label::kNear); 1682 patch_site.EmitJumpIfSmi(eax, &smi_case, Label::kNear);
1637 1683
1638 __ bind(&stub_call); 1684 __ bind(&stub_call);
1639 __ mov(eax, ecx); 1685 __ mov(eax, ecx);
1640 BinaryOpStub stub(op, mode); 1686 BinaryOpStub stub(op, mode);
1641 __ call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id()); 1687 __ call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id());
1642 patch_site.EmitPatchInfo(); 1688 patch_site.EmitPatchInfo();
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
1714 1760
1715 __ bind(&done); 1761 __ bind(&done);
1716 context()->Plug(eax); 1762 context()->Plug(eax);
1717 } 1763 }
1718 1764
1719 1765
1720 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, 1766 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr,
1721 Token::Value op, 1767 Token::Value op,
1722 OverwriteMode mode) { 1768 OverwriteMode mode) {
1723 __ pop(edx); 1769 __ pop(edx);
1770 decrement_stack_height();
1724 BinaryOpStub stub(op, mode); 1771 BinaryOpStub stub(op, mode);
1725 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. 1772 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
1726 __ call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id()); 1773 __ call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id());
1727 patch_site.EmitPatchInfo(); 1774 patch_site.EmitPatchInfo();
1728 context()->Plug(eax); 1775 context()->Plug(eax);
1729 } 1776 }
1730 1777
1731 1778
1732 void FullCodeGenerator::EmitAssignment(Expression* expr, int bailout_ast_id) { 1779 void FullCodeGenerator::EmitAssignment(Expression* expr, int bailout_ast_id) {
1733 // Invalid left-hand sides are rewritten to have a 'throw 1780 // Invalid left-hand sides are rewritten to have a 'throw
1734 // ReferenceError' on the left-hand side. 1781 // ReferenceError' on the left-hand side.
1735 if (!expr->IsValidLeftHandSide()) { 1782 if (!expr->IsValidLeftHandSide()) {
1736 VisitForEffect(expr); 1783 ASSERT(expr->AsThrow() != NULL);
1784 VisitInCurrentContext(expr); // Throw does not plug the context
1785 context()->Plug(eax);
1737 return; 1786 return;
1738 } 1787 }
1739 1788
1740 // Left-hand side can only be a property, a global or a (parameter or local) 1789 // Left-hand side can only be a property, a global or a (parameter or local)
1741 // slot. 1790 // slot.
1742 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; 1791 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
1743 LhsKind assign_type = VARIABLE; 1792 LhsKind assign_type = VARIABLE;
1744 Property* prop = expr->AsProperty(); 1793 Property* prop = expr->AsProperty();
1745 if (prop != NULL) { 1794 if (prop != NULL) {
1746 assign_type = (prop->key()->IsPropertyName()) 1795 assign_type = (prop->key()->IsPropertyName())
1747 ? NAMED_PROPERTY 1796 ? NAMED_PROPERTY
1748 : KEYED_PROPERTY; 1797 : KEYED_PROPERTY;
1749 } 1798 }
1750 1799
1751 switch (assign_type) { 1800 switch (assign_type) {
1752 case VARIABLE: { 1801 case VARIABLE: {
1753 Variable* var = expr->AsVariableProxy()->var(); 1802 Variable* var = expr->AsVariableProxy()->var();
1754 EffectContext context(this); 1803 EffectContext context(this);
1755 EmitVariableAssignment(var, Token::ASSIGN); 1804 EmitVariableAssignment(var, Token::ASSIGN);
1756 break; 1805 break;
1757 } 1806 }
1758 case NAMED_PROPERTY: { 1807 case NAMED_PROPERTY: {
1759 __ push(eax); // Preserve value. 1808 __ push(eax); // Preserve value.
1809 increment_stack_height();
1760 VisitForAccumulatorValue(prop->obj()); 1810 VisitForAccumulatorValue(prop->obj());
1761 __ mov(edx, eax); 1811 __ mov(edx, eax);
1762 __ pop(eax); // Restore value. 1812 __ pop(eax); // Restore value.
1813 decrement_stack_height();
1763 __ mov(ecx, prop->key()->AsLiteral()->handle()); 1814 __ mov(ecx, prop->key()->AsLiteral()->handle());
1764 Handle<Code> ic = is_strict_mode() 1815 Handle<Code> ic = is_strict_mode()
1765 ? isolate()->builtins()->StoreIC_Initialize_Strict() 1816 ? isolate()->builtins()->StoreIC_Initialize_Strict()
1766 : isolate()->builtins()->StoreIC_Initialize(); 1817 : isolate()->builtins()->StoreIC_Initialize();
1767 __ call(ic); 1818 __ call(ic);
1768 break; 1819 break;
1769 } 1820 }
1770 case KEYED_PROPERTY: { 1821 case KEYED_PROPERTY: {
1771 __ push(eax); // Preserve value. 1822 __ push(eax); // Preserve value.
1823 increment_stack_height();
1772 if (prop->is_synthetic()) { 1824 if (prop->is_synthetic()) {
1773 ASSERT(prop->obj()->AsVariableProxy() != NULL); 1825 ASSERT(prop->obj()->AsVariableProxy() != NULL);
1774 ASSERT(prop->key()->AsLiteral() != NULL); 1826 ASSERT(prop->key()->AsLiteral() != NULL);
1775 { AccumulatorValueContext for_object(this); 1827 { AccumulatorValueContext for_object(this);
1776 EmitVariableLoad(prop->obj()->AsVariableProxy()); 1828 EmitVariableLoad(prop->obj()->AsVariableProxy());
1777 } 1829 }
1778 __ mov(edx, eax); 1830 __ mov(edx, eax);
1779 __ SafeSet(ecx, Immediate(prop->key()->AsLiteral()->handle())); 1831 __ SafeSet(ecx, Immediate(prop->key()->AsLiteral()->handle()));
1780 } else { 1832 } else {
1781 VisitForStackValue(prop->obj()); 1833 VisitForStackValue(prop->obj());
1782 VisitForAccumulatorValue(prop->key()); 1834 VisitForAccumulatorValue(prop->key());
1783 __ mov(ecx, eax); 1835 __ mov(ecx, eax);
1784 __ pop(edx); 1836 __ pop(edx);
1837 decrement_stack_height();
1785 } 1838 }
1786 __ pop(eax); // Restore value. 1839 __ pop(eax); // Restore value.
1840 decrement_stack_height();
1787 Handle<Code> ic = is_strict_mode() 1841 Handle<Code> ic = is_strict_mode()
1788 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 1842 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
1789 : isolate()->builtins()->KeyedStoreIC_Initialize(); 1843 : isolate()->builtins()->KeyedStoreIC_Initialize();
1790 __ call(ic); 1844 __ call(ic);
1791 break; 1845 break;
1792 } 1846 }
1793 } 1847 }
1794 PrepareForBailoutForId(bailout_ast_id, TOS_REG); 1848 PrepareForBailoutForId(bailout_ast_id, TOS_REG);
1795 context()->Plug(eax); 1849 context()->Plug(eax);
1796 } 1850 }
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
1893 __ pop(result_register()); 1947 __ pop(result_register());
1894 } 1948 }
1895 1949
1896 // Record source code position before IC call. 1950 // Record source code position before IC call.
1897 SetSourcePosition(expr->position()); 1951 SetSourcePosition(expr->position());
1898 __ mov(ecx, prop->key()->AsLiteral()->handle()); 1952 __ mov(ecx, prop->key()->AsLiteral()->handle());
1899 if (expr->ends_initialization_block()) { 1953 if (expr->ends_initialization_block()) {
1900 __ mov(edx, Operand(esp, 0)); 1954 __ mov(edx, Operand(esp, 0));
1901 } else { 1955 } else {
1902 __ pop(edx); 1956 __ pop(edx);
1957 decrement_stack_height();
1903 } 1958 }
1904 Handle<Code> ic = is_strict_mode() 1959 Handle<Code> ic = is_strict_mode()
1905 ? isolate()->builtins()->StoreIC_Initialize_Strict() 1960 ? isolate()->builtins()->StoreIC_Initialize_Strict()
1906 : isolate()->builtins()->StoreIC_Initialize(); 1961 : isolate()->builtins()->StoreIC_Initialize();
1907 __ call(ic, RelocInfo::CODE_TARGET, expr->id()); 1962 __ call(ic, RelocInfo::CODE_TARGET, expr->id());
1908 1963
1909 // If the assignment ends an initialization block, revert to fast case. 1964 // If the assignment ends an initialization block, revert to fast case.
1910 if (expr->ends_initialization_block()) { 1965 if (expr->ends_initialization_block()) {
1911 __ push(eax); // Result of assignment, saved even if not needed. 1966 __ push(eax); // Result of assignment, saved even if not needed.
1912 __ push(Operand(esp, kPointerSize)); // Receiver is under value. 1967 __ push(Operand(esp, kPointerSize)); // Receiver is under value.
1913 __ CallRuntime(Runtime::kToFastProperties, 1); 1968 __ CallRuntime(Runtime::kToFastProperties, 1);
1914 __ pop(eax); 1969 __ pop(eax);
1915 __ Drop(1); 1970 __ Drop(1);
1971 decrement_stack_height();
1916 } 1972 }
1917 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 1973 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
1918 context()->Plug(eax); 1974 context()->Plug(eax);
1919 } 1975 }
1920 1976
1921 1977
1922 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { 1978 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
1923 // Assignment to a property, using a keyed store IC. 1979 // Assignment to a property, using a keyed store IC.
1924 1980
1925 // If the assignment starts a block of assignments to the same object, 1981 // If the assignment starts a block of assignments to the same object,
1926 // change to slow case to avoid the quadratic behavior of repeatedly 1982 // change to slow case to avoid the quadratic behavior of repeatedly
1927 // adding fast properties. 1983 // adding fast properties.
1928 if (expr->starts_initialization_block()) { 1984 if (expr->starts_initialization_block()) {
1929 __ push(result_register()); 1985 __ push(result_register());
1930 // Receiver is now under the key and value. 1986 // Receiver is now under the key and value.
1931 __ push(Operand(esp, 2 * kPointerSize)); 1987 __ push(Operand(esp, 2 * kPointerSize));
1932 __ CallRuntime(Runtime::kToSlowProperties, 1); 1988 __ CallRuntime(Runtime::kToSlowProperties, 1);
1933 __ pop(result_register()); 1989 __ pop(result_register());
1934 } 1990 }
1935 1991
1936 __ pop(ecx); 1992 __ pop(ecx);
1993 decrement_stack_height();
1937 if (expr->ends_initialization_block()) { 1994 if (expr->ends_initialization_block()) {
1938 __ mov(edx, Operand(esp, 0)); // Leave receiver on the stack for later. 1995 __ mov(edx, Operand(esp, 0)); // Leave receiver on the stack for later.
1939 } else { 1996 } else {
1940 __ pop(edx); 1997 __ pop(edx);
1998 decrement_stack_height();
1941 } 1999 }
1942 // Record source code position before IC call. 2000 // Record source code position before IC call.
1943 SetSourcePosition(expr->position()); 2001 SetSourcePosition(expr->position());
1944 Handle<Code> ic = is_strict_mode() 2002 Handle<Code> ic = is_strict_mode()
1945 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 2003 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
1946 : isolate()->builtins()->KeyedStoreIC_Initialize(); 2004 : isolate()->builtins()->KeyedStoreIC_Initialize();
1947 __ call(ic, RelocInfo::CODE_TARGET, expr->id()); 2005 __ call(ic, RelocInfo::CODE_TARGET, expr->id());
1948 2006
1949 // If the assignment ends an initialization block, revert to fast case. 2007 // If the assignment ends an initialization block, revert to fast case.
1950 if (expr->ends_initialization_block()) { 2008 if (expr->ends_initialization_block()) {
1951 __ pop(edx); 2009 __ pop(edx);
1952 __ push(eax); // Result of assignment, saved even if not needed. 2010 __ push(eax); // Result of assignment, saved even if not needed.
1953 __ push(edx); 2011 __ push(edx);
1954 __ CallRuntime(Runtime::kToFastProperties, 1); 2012 __ CallRuntime(Runtime::kToFastProperties, 1);
1955 __ pop(eax); 2013 __ pop(eax);
2014 decrement_stack_height();
1956 } 2015 }
1957 2016
1958 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2017 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
1959 context()->Plug(eax); 2018 context()->Plug(eax);
1960 } 2019 }
1961 2020
1962 2021
1963 void FullCodeGenerator::VisitProperty(Property* expr) { 2022 void FullCodeGenerator::VisitProperty(Property* expr) {
1964 Comment cmnt(masm_, "[ Property"); 2023 Comment cmnt(masm_, "[ Property");
1965 Expression* key = expr->key(); 2024 Expression* key = expr->key();
1966 2025
1967 if (key->IsPropertyName()) { 2026 if (key->IsPropertyName()) {
1968 VisitForAccumulatorValue(expr->obj()); 2027 VisitForAccumulatorValue(expr->obj());
1969 EmitNamedPropertyLoad(expr); 2028 EmitNamedPropertyLoad(expr);
1970 context()->Plug(eax); 2029 context()->Plug(eax);
1971 } else { 2030 } else {
1972 VisitForStackValue(expr->obj()); 2031 VisitForStackValue(expr->obj());
1973 VisitForAccumulatorValue(expr->key()); 2032 VisitForAccumulatorValue(expr->key());
1974 __ pop(edx); 2033 __ pop(edx);
2034 decrement_stack_height();
1975 EmitKeyedPropertyLoad(expr); 2035 EmitKeyedPropertyLoad(expr);
1976 context()->Plug(eax); 2036 context()->Plug(eax);
1977 } 2037 }
1978 } 2038 }
1979 2039
1980 2040
1981 void FullCodeGenerator::EmitCallWithIC(Call* expr, 2041 void FullCodeGenerator::EmitCallWithIC(Call* expr,
1982 Handle<Object> name, 2042 Handle<Object> name,
1983 RelocInfo::Mode mode) { 2043 RelocInfo::Mode mode) {
1984 // Code common for calls using the IC. 2044 // Code common for calls using the IC.
1985 ZoneList<Expression*>* args = expr->arguments(); 2045 ZoneList<Expression*>* args = expr->arguments();
1986 int arg_count = args->length(); 2046 int arg_count = args->length();
1987 { PreservePositionScope scope(masm()->positions_recorder()); 2047 { PreservePositionScope scope(masm()->positions_recorder());
1988 for (int i = 0; i < arg_count; i++) { 2048 for (int i = 0; i < arg_count; i++) {
1989 VisitForStackValue(args->at(i)); 2049 VisitForStackValue(args->at(i));
1990 } 2050 }
1991 __ Set(ecx, Immediate(name)); 2051 __ Set(ecx, Immediate(name));
1992 } 2052 }
1993 // Record source position of the IC call. 2053 // Record source position of the IC call.
1994 SetSourcePosition(expr->position()); 2054 SetSourcePosition(expr->position());
1995 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; 2055 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
1996 Handle<Code> ic = 2056 Handle<Code> ic =
1997 isolate()->stub_cache()->ComputeCallInitialize(arg_count, in_loop, mode); 2057 isolate()->stub_cache()->ComputeCallInitialize(arg_count, in_loop, mode);
1998 __ call(ic, mode, expr->id()); 2058 __ call(ic, mode, expr->id());
1999 RecordJSReturnSite(expr); 2059 RecordJSReturnSite(expr);
2000 // Restore context register. 2060 // Restore context register.
2001 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2061 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2062 decrement_stack_height(arg_count + 1);
2002 context()->Plug(eax); 2063 context()->Plug(eax);
2003 } 2064 }
2004 2065
2005 2066
2006 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, 2067 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr,
2007 Expression* key) { 2068 Expression* key) {
2008 // Load the key. 2069 // Load the key.
2009 VisitForAccumulatorValue(key); 2070 VisitForAccumulatorValue(key);
2010 2071
2011 // Swap the name of the function and the receiver on the stack to follow 2072 // Swap the name of the function and the receiver on the stack to follow
2012 // the calling convention for call ICs. 2073 // the calling convention for call ICs.
2013 __ pop(ecx); 2074 __ pop(ecx);
2014 __ push(eax); 2075 __ push(eax);
2015 __ push(ecx); 2076 __ push(ecx);
2077 increment_stack_height();
2016 2078
2017 // Load the arguments. 2079 // Load the arguments.
2018 ZoneList<Expression*>* args = expr->arguments(); 2080 ZoneList<Expression*>* args = expr->arguments();
2019 int arg_count = args->length(); 2081 int arg_count = args->length();
2020 { PreservePositionScope scope(masm()->positions_recorder()); 2082 { PreservePositionScope scope(masm()->positions_recorder());
2021 for (int i = 0; i < arg_count; i++) { 2083 for (int i = 0; i < arg_count; i++) {
2022 VisitForStackValue(args->at(i)); 2084 VisitForStackValue(args->at(i));
2023 } 2085 }
2024 } 2086 }
2025 // Record source position of the IC call. 2087 // Record source position of the IC call.
2026 SetSourcePosition(expr->position()); 2088 SetSourcePosition(expr->position());
2027 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; 2089 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
2028 Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedCallInitialize( 2090 Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedCallInitialize(
2029 arg_count, in_loop); 2091 arg_count, in_loop);
2030 __ mov(ecx, Operand(esp, (arg_count + 1) * kPointerSize)); // Key. 2092 __ mov(ecx, Operand(esp, (arg_count + 1) * kPointerSize)); // Key.
2031 __ call(ic, RelocInfo::CODE_TARGET, expr->id()); 2093 __ call(ic, RelocInfo::CODE_TARGET, expr->id());
2032 RecordJSReturnSite(expr); 2094 RecordJSReturnSite(expr);
2033 // Restore context register. 2095 // Restore context register.
2034 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2096 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2097 decrement_stack_height(arg_count + 1);
2035 context()->DropAndPlug(1, eax); // Drop the key still on the stack. 2098 context()->DropAndPlug(1, eax); // Drop the key still on the stack.
2036 } 2099 }
2037 2100
2038 2101
2039 void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) { 2102 void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) {
2040 // Code common for calls using the call stub. 2103 // Code common for calls using the call stub.
2041 ZoneList<Expression*>* args = expr->arguments(); 2104 ZoneList<Expression*>* args = expr->arguments();
2042 int arg_count = args->length(); 2105 int arg_count = args->length();
2043 { PreservePositionScope scope(masm()->positions_recorder()); 2106 { PreservePositionScope scope(masm()->positions_recorder());
2044 for (int i = 0; i < arg_count; i++) { 2107 for (int i = 0; i < arg_count; i++) {
2045 VisitForStackValue(args->at(i)); 2108 VisitForStackValue(args->at(i));
2046 } 2109 }
2047 } 2110 }
2048 // Record source position for debugger. 2111 // Record source position for debugger.
2049 SetSourcePosition(expr->position()); 2112 SetSourcePosition(expr->position());
2050 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; 2113 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
2051 CallFunctionStub stub(arg_count, in_loop, flags); 2114 CallFunctionStub stub(arg_count, in_loop, flags);
2052 __ CallStub(&stub); 2115 __ CallStub(&stub);
2053 RecordJSReturnSite(expr); 2116 RecordJSReturnSite(expr);
2054 // Restore context register. 2117 // Restore context register.
2055 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2118 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2119
2120 decrement_stack_height(arg_count + 1);
2056 context()->DropAndPlug(1, eax); 2121 context()->DropAndPlug(1, eax);
2057 } 2122 }
2058 2123
2059 2124
2060 void FullCodeGenerator::EmitResolvePossiblyDirectEval(ResolveEvalFlag flag, 2125 void FullCodeGenerator::EmitResolvePossiblyDirectEval(ResolveEvalFlag flag,
2061 int arg_count) { 2126 int arg_count) {
2062 // Push copy of the first argument or undefined if it doesn't exist. 2127 // Push copy of the first argument or undefined if it doesn't exist.
2063 if (arg_count > 0) { 2128 if (arg_count > 0) {
2064 __ push(Operand(esp, arg_count * kPointerSize)); 2129 __ push(Operand(esp, arg_count * kPointerSize));
2065 } else { 2130 } else {
(...skipping 27 matching lines...) Expand all
2093 // In a call to eval, we first call %ResolvePossiblyDirectEval to 2158 // In a call to eval, we first call %ResolvePossiblyDirectEval to
2094 // resolve the function we need to call and the receiver of the 2159 // resolve the function we need to call and the receiver of the
2095 // call. Then we call the resolved function using the given 2160 // call. Then we call the resolved function using the given
2096 // arguments. 2161 // arguments.
2097 ZoneList<Expression*>* args = expr->arguments(); 2162 ZoneList<Expression*>* args = expr->arguments();
2098 int arg_count = args->length(); 2163 int arg_count = args->length();
2099 { PreservePositionScope pos_scope(masm()->positions_recorder()); 2164 { PreservePositionScope pos_scope(masm()->positions_recorder());
2100 VisitForStackValue(fun); 2165 VisitForStackValue(fun);
2101 // Reserved receiver slot. 2166 // Reserved receiver slot.
2102 __ push(Immediate(isolate()->factory()->undefined_value())); 2167 __ push(Immediate(isolate()->factory()->undefined_value()));
2103 2168 increment_stack_height();
2104 // Push the arguments. 2169 // Push the arguments.
2105 for (int i = 0; i < arg_count; i++) { 2170 for (int i = 0; i < arg_count; i++) {
2106 VisitForStackValue(args->at(i)); 2171 VisitForStackValue(args->at(i));
2107 } 2172 }
2108 2173
2109 // If we know that eval can only be shadowed by eval-introduced 2174 // If we know that eval can only be shadowed by eval-introduced
2110 // variables we attempt to load the global eval function directly 2175 // variables we attempt to load the global eval function directly
2111 // in generated code. If we succeed, there is no need to perform a 2176 // in generated code. If we succeed, there is no need to perform a
2112 // context lookup in the runtime system. 2177 // context lookup in the runtime system.
2113 Label done; 2178 Label done;
(...skipping 23 matching lines...) Expand all
2137 __ mov(Operand(esp, (arg_count + 1) * kPointerSize), eax); 2202 __ mov(Operand(esp, (arg_count + 1) * kPointerSize), eax);
2138 } 2203 }
2139 // Record source position for debugger. 2204 // Record source position for debugger.
2140 SetSourcePosition(expr->position()); 2205 SetSourcePosition(expr->position());
2141 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; 2206 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
2142 CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_IMPLICIT); 2207 CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_IMPLICIT);
2143 __ CallStub(&stub); 2208 __ CallStub(&stub);
2144 RecordJSReturnSite(expr); 2209 RecordJSReturnSite(expr);
2145 // Restore context register. 2210 // Restore context register.
2146 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2211 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2212 decrement_stack_height(arg_count + 1); // Function is left on the stack.
2147 context()->DropAndPlug(1, eax); 2213 context()->DropAndPlug(1, eax);
2148 } else if (var != NULL && !var->is_this() && var->is_global()) { 2214 } else if (var != NULL && !var->is_this() && var->is_global()) {
2149 // Push global object as receiver for the call IC. 2215 // Push global object as receiver for the call IC.
2150 __ push(GlobalObjectOperand()); 2216 __ push(GlobalObjectOperand());
2217 increment_stack_height();
2151 EmitCallWithIC(expr, var->name(), RelocInfo::CODE_TARGET_CONTEXT); 2218 EmitCallWithIC(expr, var->name(), RelocInfo::CODE_TARGET_CONTEXT);
2152 } else if (var != NULL && var->AsSlot() != NULL && 2219 } else if (var != NULL && var->AsSlot() != NULL &&
2153 var->AsSlot()->type() == Slot::LOOKUP) { 2220 var->AsSlot()->type() == Slot::LOOKUP) {
2154 // Call to a lookup slot (dynamically introduced variable). 2221 // Call to a lookup slot (dynamically introduced variable).
2155 Label slow, done; 2222 Label slow, done;
2156 2223
2157 { PreservePositionScope scope(masm()->positions_recorder()); 2224 { PreservePositionScope scope(masm()->positions_recorder());
2158 // Generate code for loading from variables potentially shadowed 2225 // Generate code for loading from variables potentially shadowed
2159 // by eval-introduced variables. 2226 // by eval-introduced variables.
2160 EmitDynamicLoadFromSlotFastCase(var->AsSlot(), 2227 EmitDynamicLoadFromSlotFastCase(var->AsSlot(),
2161 NOT_INSIDE_TYPEOF, 2228 NOT_INSIDE_TYPEOF,
2162 &slow, 2229 &slow,
2163 &done); 2230 &done);
2164 } 2231 }
2165 2232
2166 __ bind(&slow); 2233 __ bind(&slow);
2167 // Call the runtime to find the function to call (returned in eax) 2234 // Call the runtime to find the function to call (returned in eax)
2168 // and the object holding it (returned in edx). 2235 // and the object holding it (returned in edx).
2169 __ push(context_register()); 2236 __ push(context_register());
2170 __ push(Immediate(var->name())); 2237 __ push(Immediate(var->name()));
2171 __ CallRuntime(Runtime::kLoadContextSlot, 2); 2238 __ CallRuntime(Runtime::kLoadContextSlot, 2);
2172 __ push(eax); // Function. 2239 __ push(eax); // Function.
2240 increment_stack_height();
2173 __ push(edx); // Receiver. 2241 __ push(edx); // Receiver.
2242 increment_stack_height();
2174 2243
2175 // If fast case code has been generated, emit code to push the 2244 // If fast case code has been generated, emit code to push the
2176 // function and receiver and have the slow path jump around this 2245 // function and receiver and have the slow path jump around this
2177 // code. 2246 // code.
2178 if (done.is_linked()) { 2247 if (done.is_linked()) {
2179 Label call; 2248 Label call;
2180 __ jmp(&call); 2249 __ jmp(&call);
2181 __ bind(&done); 2250 __ bind(&done);
2182 // Push function. 2251 // Push function. Stack height already incremented in slow case above.
2183 __ push(eax); 2252 __ push(eax);
2184 // The receiver is implicitly the global receiver. Indicate this 2253 // The receiver is implicitly the global receiver. Indicate this
2185 // by passing the hole to the call function stub. 2254 // by passing the hole to the call function stub.
2186 __ push(Immediate(isolate()->factory()->the_hole_value())); 2255 __ push(Immediate(isolate()->factory()->the_hole_value()));
2187 __ bind(&call); 2256 __ bind(&call);
2188 } 2257 }
2189 2258
2190 // The receiver is either the global receiver or an object found 2259 // The receiver is either the global receiver or an object found
2191 // by LoadContextSlot. That object could be the hole if the 2260 // by LoadContextSlot. That object could be the hole if the
2192 // receiver is implicitly the global object. 2261 // receiver is implicitly the global object.
(...skipping 25 matching lines...) Expand all
2218 ASSERT(prop->key()->AsLiteral()->handle()->IsSmi()); 2287 ASSERT(prop->key()->AsLiteral()->handle()->IsSmi());
2219 __ mov(eax, prop->key()->AsLiteral()->handle()); 2288 __ mov(eax, prop->key()->AsLiteral()->handle());
2220 2289
2221 // Record source code position for IC call. 2290 // Record source code position for IC call.
2222 SetSourcePosition(prop->position()); 2291 SetSourcePosition(prop->position());
2223 2292
2224 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); 2293 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
2225 __ call(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop)); 2294 __ call(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop));
2226 // Push result (function). 2295 // Push result (function).
2227 __ push(eax); 2296 __ push(eax);
2297 increment_stack_height();
2228 // Push Global receiver. 2298 // Push Global receiver.
2229 __ mov(ecx, GlobalObjectOperand()); 2299 __ mov(ecx, GlobalObjectOperand());
2230 __ push(FieldOperand(ecx, GlobalObject::kGlobalReceiverOffset)); 2300 __ push(FieldOperand(ecx, GlobalObject::kGlobalReceiverOffset));
2301 increment_stack_height();
2231 EmitCallWithStub(expr, NO_CALL_FUNCTION_FLAGS); 2302 EmitCallWithStub(expr, NO_CALL_FUNCTION_FLAGS);
2232 } else { 2303 } else {
2233 { PreservePositionScope scope(masm()->positions_recorder()); 2304 { PreservePositionScope scope(masm()->positions_recorder());
2234 VisitForStackValue(prop->obj()); 2305 VisitForStackValue(prop->obj());
2235 } 2306 }
2236 EmitKeyedCallWithIC(expr, prop->key()); 2307 EmitKeyedCallWithIC(expr, prop->key());
2237 } 2308 }
2238 } 2309 }
2239 } else { 2310 } else {
2240 { PreservePositionScope scope(masm()->positions_recorder()); 2311 { PreservePositionScope scope(masm()->positions_recorder());
2241 VisitForStackValue(fun); 2312 VisitForStackValue(fun);
2242 } 2313 }
2243 // Load global receiver object. 2314 // Load global receiver object.
2244 __ mov(ebx, GlobalObjectOperand()); 2315 __ mov(ebx, GlobalObjectOperand());
2245 __ push(FieldOperand(ebx, GlobalObject::kGlobalReceiverOffset)); 2316 __ push(FieldOperand(ebx, GlobalObject::kGlobalReceiverOffset));
2317 increment_stack_height();
2246 // Emit function call. 2318 // Emit function call.
2247 EmitCallWithStub(expr, NO_CALL_FUNCTION_FLAGS); 2319 EmitCallWithStub(expr, NO_CALL_FUNCTION_FLAGS);
2248 } 2320 }
2249 2321
2250 #ifdef DEBUG 2322 #ifdef DEBUG
2251 // RecordJSReturnSite should have been called. 2323 // RecordJSReturnSite should have been called.
2252 ASSERT(expr->return_is_recorded_); 2324 ASSERT(expr->return_is_recorded_);
2253 #endif 2325 #endif
2254 } 2326 }
2255 2327
(...skipping 20 matching lines...) Expand all
2276 // constructor invocation. 2348 // constructor invocation.
2277 SetSourcePosition(expr->position()); 2349 SetSourcePosition(expr->position());
2278 2350
2279 // Load function and argument count into edi and eax. 2351 // Load function and argument count into edi and eax.
2280 __ SafeSet(eax, Immediate(arg_count)); 2352 __ SafeSet(eax, Immediate(arg_count));
2281 __ mov(edi, Operand(esp, arg_count * kPointerSize)); 2353 __ mov(edi, Operand(esp, arg_count * kPointerSize));
2282 2354
2283 Handle<Code> construct_builtin = 2355 Handle<Code> construct_builtin =
2284 isolate()->builtins()->JSConstructCall(); 2356 isolate()->builtins()->JSConstructCall();
2285 __ call(construct_builtin, RelocInfo::CONSTRUCT_CALL); 2357 __ call(construct_builtin, RelocInfo::CONSTRUCT_CALL);
2358
2359 decrement_stack_height(arg_count + 1);
2286 context()->Plug(eax); 2360 context()->Plug(eax);
2287 } 2361 }
2288 2362
2289 2363
2290 void FullCodeGenerator::EmitIsSmi(ZoneList<Expression*>* args) { 2364 void FullCodeGenerator::EmitIsSmi(ZoneList<Expression*>* args) {
2291 ASSERT(args->length() == 1); 2365 ASSERT(args->length() == 1);
2292 2366
2293 VisitForAccumulatorValue(args->at(0)); 2367 VisitForAccumulatorValue(args->at(0));
2294 2368
2295 Label materialize_true, materialize_false; 2369 Label materialize_true, materialize_false;
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after
2588 VisitForAccumulatorValue(args->at(1)); 2662 VisitForAccumulatorValue(args->at(1));
2589 2663
2590 Label materialize_true, materialize_false; 2664 Label materialize_true, materialize_false;
2591 Label* if_true = NULL; 2665 Label* if_true = NULL;
2592 Label* if_false = NULL; 2666 Label* if_false = NULL;
2593 Label* fall_through = NULL; 2667 Label* fall_through = NULL;
2594 context()->PrepareTest(&materialize_true, &materialize_false, 2668 context()->PrepareTest(&materialize_true, &materialize_false,
2595 &if_true, &if_false, &fall_through); 2669 &if_true, &if_false, &fall_through);
2596 2670
2597 __ pop(ebx); 2671 __ pop(ebx);
2672 decrement_stack_height();
2598 __ cmp(eax, Operand(ebx)); 2673 __ cmp(eax, Operand(ebx));
2599 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); 2674 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
2600 Split(equal, if_true, if_false, fall_through); 2675 Split(equal, if_true, if_false, fall_through);
2601 2676
2602 context()->Plug(if_true, if_false); 2677 context()->Plug(if_true, if_false);
2603 } 2678 }
2604 2679
2605 2680
2606 void FullCodeGenerator::EmitArguments(ZoneList<Expression*>* args) { 2681 void FullCodeGenerator::EmitArguments(ZoneList<Expression*>* args) {
2607 ASSERT(args->length() == 1); 2682 ASSERT(args->length() == 1);
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
2702 // 0 (literal string): The type of logging (corresponds to the flags). 2777 // 0 (literal string): The type of logging (corresponds to the flags).
2703 // This is used to determine whether or not to generate the log call. 2778 // This is used to determine whether or not to generate the log call.
2704 // 1 (string): Format string. Access the string at argument index 2 2779 // 1 (string): Format string. Access the string at argument index 2
2705 // with '%2s' (see Logger::LogRuntime for all the formats). 2780 // with '%2s' (see Logger::LogRuntime for all the formats).
2706 // 2 (array): Arguments to the format string. 2781 // 2 (array): Arguments to the format string.
2707 ASSERT_EQ(args->length(), 3); 2782 ASSERT_EQ(args->length(), 3);
2708 if (CodeGenerator::ShouldGenerateLog(args->at(0))) { 2783 if (CodeGenerator::ShouldGenerateLog(args->at(0))) {
2709 VisitForStackValue(args->at(1)); 2784 VisitForStackValue(args->at(1));
2710 VisitForStackValue(args->at(2)); 2785 VisitForStackValue(args->at(2));
2711 __ CallRuntime(Runtime::kLog, 2); 2786 __ CallRuntime(Runtime::kLog, 2);
2787 decrement_stack_height(2);
2712 } 2788 }
2713 // Finally, we're expected to leave a value on the top of the stack. 2789 // Finally, we're expected to leave a value on the top of the stack.
2714 __ mov(eax, isolate()->factory()->undefined_value()); 2790 __ mov(eax, isolate()->factory()->undefined_value());
2715 context()->Plug(eax); 2791 context()->Plug(eax);
2716 } 2792 }
2717 2793
2718 2794
2719 void FullCodeGenerator::EmitRandomHeapNumber(ZoneList<Expression*>* args) { 2795 void FullCodeGenerator::EmitRandomHeapNumber(ZoneList<Expression*>* args) {
2720 ASSERT(args->length() == 0); 2796 ASSERT(args->length() == 0);
2721 2797
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
2767 2843
2768 2844
2769 void FullCodeGenerator::EmitSubString(ZoneList<Expression*>* args) { 2845 void FullCodeGenerator::EmitSubString(ZoneList<Expression*>* args) {
2770 // Load the arguments on the stack and call the stub. 2846 // Load the arguments on the stack and call the stub.
2771 SubStringStub stub; 2847 SubStringStub stub;
2772 ASSERT(args->length() == 3); 2848 ASSERT(args->length() == 3);
2773 VisitForStackValue(args->at(0)); 2849 VisitForStackValue(args->at(0));
2774 VisitForStackValue(args->at(1)); 2850 VisitForStackValue(args->at(1));
2775 VisitForStackValue(args->at(2)); 2851 VisitForStackValue(args->at(2));
2776 __ CallStub(&stub); 2852 __ CallStub(&stub);
2853 decrement_stack_height(3);
2777 context()->Plug(eax); 2854 context()->Plug(eax);
2778 } 2855 }
2779 2856
2780 2857
2781 void FullCodeGenerator::EmitRegExpExec(ZoneList<Expression*>* args) { 2858 void FullCodeGenerator::EmitRegExpExec(ZoneList<Expression*>* args) {
2782 // Load the arguments on the stack and call the stub. 2859 // Load the arguments on the stack and call the stub.
2783 RegExpExecStub stub; 2860 RegExpExecStub stub;
2784 ASSERT(args->length() == 4); 2861 ASSERT(args->length() == 4);
2785 VisitForStackValue(args->at(0)); 2862 VisitForStackValue(args->at(0));
2786 VisitForStackValue(args->at(1)); 2863 VisitForStackValue(args->at(1));
2787 VisitForStackValue(args->at(2)); 2864 VisitForStackValue(args->at(2));
2788 VisitForStackValue(args->at(3)); 2865 VisitForStackValue(args->at(3));
2789 __ CallStub(&stub); 2866 __ CallStub(&stub);
2867 decrement_stack_height(4);
2790 context()->Plug(eax); 2868 context()->Plug(eax);
2791 } 2869 }
2792 2870
2793 2871
2794 void FullCodeGenerator::EmitValueOf(ZoneList<Expression*>* args) { 2872 void FullCodeGenerator::EmitValueOf(ZoneList<Expression*>* args) {
2795 ASSERT(args->length() == 1); 2873 ASSERT(args->length() == 1);
2796 2874
2797 VisitForAccumulatorValue(args->at(0)); // Load the object. 2875 VisitForAccumulatorValue(args->at(0)); // Load the object.
2798 2876
2799 Label done; 2877 Label done;
(...skipping 14 matching lines...) Expand all
2814 ASSERT(args->length() == 2); 2892 ASSERT(args->length() == 2);
2815 VisitForStackValue(args->at(0)); 2893 VisitForStackValue(args->at(0));
2816 VisitForStackValue(args->at(1)); 2894 VisitForStackValue(args->at(1));
2817 2895
2818 if (CpuFeatures::IsSupported(SSE2)) { 2896 if (CpuFeatures::IsSupported(SSE2)) {
2819 MathPowStub stub; 2897 MathPowStub stub;
2820 __ CallStub(&stub); 2898 __ CallStub(&stub);
2821 } else { 2899 } else {
2822 __ CallRuntime(Runtime::kMath_pow, 2); 2900 __ CallRuntime(Runtime::kMath_pow, 2);
2823 } 2901 }
2902 decrement_stack_height(2);
2824 context()->Plug(eax); 2903 context()->Plug(eax);
2825 } 2904 }
2826 2905
2827 2906
2828 void FullCodeGenerator::EmitSetValueOf(ZoneList<Expression*>* args) { 2907 void FullCodeGenerator::EmitSetValueOf(ZoneList<Expression*>* args) {
2829 ASSERT(args->length() == 2); 2908 ASSERT(args->length() == 2);
2830 2909
2831 VisitForStackValue(args->at(0)); // Load the object. 2910 VisitForStackValue(args->at(0)); // Load the object.
2832 VisitForAccumulatorValue(args->at(1)); // Load the value. 2911 VisitForAccumulatorValue(args->at(1)); // Load the value.
2833 __ pop(ebx); // eax = value. ebx = object. 2912 __ pop(ebx); // eax = value. ebx = object.
2913 decrement_stack_height();
2834 2914
2835 Label done; 2915 Label done;
2836 // If the object is a smi, return the value. 2916 // If the object is a smi, return the value.
2837 __ JumpIfSmi(ebx, &done, Label::kNear); 2917 __ JumpIfSmi(ebx, &done, Label::kNear);
2838 2918
2839 // If the object is not a value type, return the value. 2919 // If the object is not a value type, return the value.
2840 __ CmpObjectType(ebx, JS_VALUE_TYPE, ecx); 2920 __ CmpObjectType(ebx, JS_VALUE_TYPE, ecx);
2841 __ j(not_equal, &done, Label::kNear); 2921 __ j(not_equal, &done, Label::kNear);
2842 2922
2843 // Store the value. 2923 // Store the value.
2844 __ mov(FieldOperand(ebx, JSValue::kValueOffset), eax); 2924 __ mov(FieldOperand(ebx, JSValue::kValueOffset), eax);
2845 // Update the write barrier. Save the value as it will be 2925 // Update the write barrier. Save the value as it will be
2846 // overwritten by the write barrier code and is needed afterward. 2926 // overwritten by the write barrier code and is needed afterward.
2847 __ mov(edx, eax); 2927 __ mov(edx, eax);
2848 __ RecordWrite(ebx, JSValue::kValueOffset, edx, ecx); 2928 __ RecordWrite(ebx, JSValue::kValueOffset, edx, ecx);
2849 2929
2850 __ bind(&done); 2930 __ bind(&done);
2851 context()->Plug(eax); 2931 context()->Plug(eax);
2852 } 2932 }
2853 2933
2854 2934
2855 void FullCodeGenerator::EmitNumberToString(ZoneList<Expression*>* args) { 2935 void FullCodeGenerator::EmitNumberToString(ZoneList<Expression*>* args) {
2856 ASSERT_EQ(args->length(), 1); 2936 ASSERT_EQ(args->length(), 1);
2857 2937
2858 // Load the argument on the stack and call the stub. 2938 // Load the argument on the stack and call the stub.
2859 VisitForStackValue(args->at(0)); 2939 VisitForStackValue(args->at(0));
2860 2940
2861 NumberToStringStub stub; 2941 NumberToStringStub stub;
2862 __ CallStub(&stub); 2942 __ CallStub(&stub);
2943 decrement_stack_height();
2863 context()->Plug(eax); 2944 context()->Plug(eax);
2864 } 2945 }
2865 2946
2866 2947
2867 void FullCodeGenerator::EmitStringCharFromCode(ZoneList<Expression*>* args) { 2948 void FullCodeGenerator::EmitStringCharFromCode(ZoneList<Expression*>* args) {
2868 ASSERT(args->length() == 1); 2949 ASSERT(args->length() == 1);
2869 2950
2870 VisitForAccumulatorValue(args->at(0)); 2951 VisitForAccumulatorValue(args->at(0));
2871 2952
2872 Label done; 2953 Label done;
(...skipping 14 matching lines...) Expand all
2887 2968
2888 VisitForStackValue(args->at(0)); 2969 VisitForStackValue(args->at(0));
2889 VisitForAccumulatorValue(args->at(1)); 2970 VisitForAccumulatorValue(args->at(1));
2890 2971
2891 Register object = ebx; 2972 Register object = ebx;
2892 Register index = eax; 2973 Register index = eax;
2893 Register scratch = ecx; 2974 Register scratch = ecx;
2894 Register result = edx; 2975 Register result = edx;
2895 2976
2896 __ pop(object); 2977 __ pop(object);
2978 decrement_stack_height();
2897 2979
2898 Label need_conversion; 2980 Label need_conversion;
2899 Label index_out_of_range; 2981 Label index_out_of_range;
2900 Label done; 2982 Label done;
2901 StringCharCodeAtGenerator generator(object, 2983 StringCharCodeAtGenerator generator(object,
2902 index, 2984 index,
2903 scratch, 2985 scratch,
2904 result, 2986 result,
2905 &need_conversion, 2987 &need_conversion,
2906 &need_conversion, 2988 &need_conversion,
(...skipping 28 matching lines...) Expand all
2935 VisitForStackValue(args->at(0)); 3017 VisitForStackValue(args->at(0));
2936 VisitForAccumulatorValue(args->at(1)); 3018 VisitForAccumulatorValue(args->at(1));
2937 3019
2938 Register object = ebx; 3020 Register object = ebx;
2939 Register index = eax; 3021 Register index = eax;
2940 Register scratch1 = ecx; 3022 Register scratch1 = ecx;
2941 Register scratch2 = edx; 3023 Register scratch2 = edx;
2942 Register result = eax; 3024 Register result = eax;
2943 3025
2944 __ pop(object); 3026 __ pop(object);
3027 decrement_stack_height();
2945 3028
2946 Label need_conversion; 3029 Label need_conversion;
2947 Label index_out_of_range; 3030 Label index_out_of_range;
2948 Label done; 3031 Label done;
2949 StringCharAtGenerator generator(object, 3032 StringCharAtGenerator generator(object,
2950 index, 3033 index,
2951 scratch1, 3034 scratch1,
2952 scratch2, 3035 scratch2,
2953 result, 3036 result,
2954 &need_conversion, 3037 &need_conversion,
(...skipping 24 matching lines...) Expand all
2979 3062
2980 3063
2981 void FullCodeGenerator::EmitStringAdd(ZoneList<Expression*>* args) { 3064 void FullCodeGenerator::EmitStringAdd(ZoneList<Expression*>* args) {
2982 ASSERT_EQ(2, args->length()); 3065 ASSERT_EQ(2, args->length());
2983 3066
2984 VisitForStackValue(args->at(0)); 3067 VisitForStackValue(args->at(0));
2985 VisitForStackValue(args->at(1)); 3068 VisitForStackValue(args->at(1));
2986 3069
2987 StringAddStub stub(NO_STRING_ADD_FLAGS); 3070 StringAddStub stub(NO_STRING_ADD_FLAGS);
2988 __ CallStub(&stub); 3071 __ CallStub(&stub);
3072 decrement_stack_height(2);
2989 context()->Plug(eax); 3073 context()->Plug(eax);
2990 } 3074 }
2991 3075
2992 3076
2993 void FullCodeGenerator::EmitStringCompare(ZoneList<Expression*>* args) { 3077 void FullCodeGenerator::EmitStringCompare(ZoneList<Expression*>* args) {
2994 ASSERT_EQ(2, args->length()); 3078 ASSERT_EQ(2, args->length());
2995 3079
2996 VisitForStackValue(args->at(0)); 3080 VisitForStackValue(args->at(0));
2997 VisitForStackValue(args->at(1)); 3081 VisitForStackValue(args->at(1));
2998 3082
2999 StringCompareStub stub; 3083 StringCompareStub stub;
3000 __ CallStub(&stub); 3084 __ CallStub(&stub);
3085 decrement_stack_height(2);
3001 context()->Plug(eax); 3086 context()->Plug(eax);
3002 } 3087 }
3003 3088
3004 3089
3005 void FullCodeGenerator::EmitMathSin(ZoneList<Expression*>* args) { 3090 void FullCodeGenerator::EmitMathSin(ZoneList<Expression*>* args) {
3006 // Load the argument on the stack and call the stub. 3091 // Load the argument on the stack and call the stub.
3007 TranscendentalCacheStub stub(TranscendentalCache::SIN, 3092 TranscendentalCacheStub stub(TranscendentalCache::SIN,
3008 TranscendentalCacheStub::TAGGED); 3093 TranscendentalCacheStub::TAGGED);
3009 ASSERT(args->length() == 1); 3094 ASSERT(args->length() == 1);
3010 VisitForStackValue(args->at(0)); 3095 VisitForStackValue(args->at(0));
3011 __ CallStub(&stub); 3096 __ CallStub(&stub);
3097 decrement_stack_height();
3012 context()->Plug(eax); 3098 context()->Plug(eax);
3013 } 3099 }
3014 3100
3015 3101
3016 void FullCodeGenerator::EmitMathCos(ZoneList<Expression*>* args) { 3102 void FullCodeGenerator::EmitMathCos(ZoneList<Expression*>* args) {
3017 // Load the argument on the stack and call the stub. 3103 // Load the argument on the stack and call the stub.
3018 TranscendentalCacheStub stub(TranscendentalCache::COS, 3104 TranscendentalCacheStub stub(TranscendentalCache::COS,
3019 TranscendentalCacheStub::TAGGED); 3105 TranscendentalCacheStub::TAGGED);
3020 ASSERT(args->length() == 1); 3106 ASSERT(args->length() == 1);
3021 VisitForStackValue(args->at(0)); 3107 VisitForStackValue(args->at(0));
3022 __ CallStub(&stub); 3108 __ CallStub(&stub);
3109 decrement_stack_height();
3023 context()->Plug(eax); 3110 context()->Plug(eax);
3024 } 3111 }
3025 3112
3026 3113
3027 void FullCodeGenerator::EmitMathLog(ZoneList<Expression*>* args) { 3114 void FullCodeGenerator::EmitMathLog(ZoneList<Expression*>* args) {
3028 // Load the argument on the stack and call the stub. 3115 // Load the argument on the stack and call the stub.
3029 TranscendentalCacheStub stub(TranscendentalCache::LOG, 3116 TranscendentalCacheStub stub(TranscendentalCache::LOG,
3030 TranscendentalCacheStub::TAGGED); 3117 TranscendentalCacheStub::TAGGED);
3031 ASSERT(args->length() == 1); 3118 ASSERT(args->length() == 1);
3032 VisitForStackValue(args->at(0)); 3119 VisitForStackValue(args->at(0));
3033 __ CallStub(&stub); 3120 __ CallStub(&stub);
3121 decrement_stack_height();
3034 context()->Plug(eax); 3122 context()->Plug(eax);
3035 } 3123 }
3036 3124
3037 3125
3038 void FullCodeGenerator::EmitMathSqrt(ZoneList<Expression*>* args) { 3126 void FullCodeGenerator::EmitMathSqrt(ZoneList<Expression*>* args) {
3039 // Load the argument on the stack and call the runtime function. 3127 // Load the argument on the stack and call the runtime function.
3040 ASSERT(args->length() == 1); 3128 ASSERT(args->length() == 1);
3041 VisitForStackValue(args->at(0)); 3129 VisitForStackValue(args->at(0));
3042 __ CallRuntime(Runtime::kMath_sqrt, 1); 3130 __ CallRuntime(Runtime::kMath_sqrt, 1);
3131 decrement_stack_height();
3043 context()->Plug(eax); 3132 context()->Plug(eax);
3044 } 3133 }
3045 3134
3046 3135
3047 void FullCodeGenerator::EmitCallFunction(ZoneList<Expression*>* args) { 3136 void FullCodeGenerator::EmitCallFunction(ZoneList<Expression*>* args) {
3048 ASSERT(args->length() >= 2); 3137 ASSERT(args->length() >= 2);
3049 3138
3050 int arg_count = args->length() - 2; // 2 ~ receiver and function. 3139 int arg_count = args->length() - 2; // 2 ~ receiver and function.
3051 for (int i = 0; i < arg_count + 1; ++i) { 3140 for (int i = 0; i < arg_count + 1; ++i) {
3052 VisitForStackValue(args->at(i)); 3141 VisitForStackValue(args->at(i));
3053 } 3142 }
3054 VisitForAccumulatorValue(args->last()); // Function. 3143 VisitForAccumulatorValue(args->last()); // Function.
3055 3144
3056 // InvokeFunction requires the function in edi. Move it in there. 3145 // InvokeFunction requires the function in edi. Move it in there.
3057 __ mov(edi, result_register()); 3146 __ mov(edi, result_register());
3058 ParameterCount count(arg_count); 3147 ParameterCount count(arg_count);
3059 __ InvokeFunction(edi, count, CALL_FUNCTION, 3148 __ InvokeFunction(edi, count, CALL_FUNCTION,
3060 NullCallWrapper(), CALL_AS_METHOD); 3149 NullCallWrapper(), CALL_AS_METHOD);
3061 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 3150 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
3151 decrement_stack_height(arg_count + 1);
3062 context()->Plug(eax); 3152 context()->Plug(eax);
3063 } 3153 }
3064 3154
3065 3155
3066 void FullCodeGenerator::EmitRegExpConstructResult(ZoneList<Expression*>* args) { 3156 void FullCodeGenerator::EmitRegExpConstructResult(ZoneList<Expression*>* args) {
3067 // Load the arguments on the stack and call the stub. 3157 // Load the arguments on the stack and call the stub.
3068 RegExpConstructResultStub stub; 3158 RegExpConstructResultStub stub;
3069 ASSERT(args->length() == 3); 3159 ASSERT(args->length() == 3);
3070 VisitForStackValue(args->at(0)); 3160 VisitForStackValue(args->at(0));
3071 VisitForStackValue(args->at(1)); 3161 VisitForStackValue(args->at(1));
3072 VisitForStackValue(args->at(2)); 3162 VisitForStackValue(args->at(2));
3073 __ CallStub(&stub); 3163 __ CallStub(&stub);
3164 decrement_stack_height(3);
3074 context()->Plug(eax); 3165 context()->Plug(eax);
3075 } 3166 }
3076 3167
3077 3168
3078 void FullCodeGenerator::EmitSwapElements(ZoneList<Expression*>* args) { 3169 void FullCodeGenerator::EmitSwapElements(ZoneList<Expression*>* args) {
3079 ASSERT(args->length() == 3); 3170 ASSERT(args->length() == 3);
3080 VisitForStackValue(args->at(0)); 3171 VisitForStackValue(args->at(0));
3081 VisitForStackValue(args->at(1)); 3172 VisitForStackValue(args->at(1));
3082 VisitForStackValue(args->at(2)); 3173 VisitForStackValue(args->at(2));
3083 Label done; 3174 Label done;
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
3137 __ bind(&new_space); 3228 __ bind(&new_space);
3138 // We are done. Drop elements from the stack, and return undefined. 3229 // We are done. Drop elements from the stack, and return undefined.
3139 __ add(Operand(esp), Immediate(3 * kPointerSize)); 3230 __ add(Operand(esp), Immediate(3 * kPointerSize));
3140 __ mov(eax, isolate()->factory()->undefined_value()); 3231 __ mov(eax, isolate()->factory()->undefined_value());
3141 __ jmp(&done); 3232 __ jmp(&done);
3142 3233
3143 __ bind(&slow_case); 3234 __ bind(&slow_case);
3144 __ CallRuntime(Runtime::kSwapElements, 3); 3235 __ CallRuntime(Runtime::kSwapElements, 3);
3145 3236
3146 __ bind(&done); 3237 __ bind(&done);
3238 decrement_stack_height(3);
3147 context()->Plug(eax); 3239 context()->Plug(eax);
3148 } 3240 }
3149 3241
3150 3242
3151 void FullCodeGenerator::EmitGetFromCache(ZoneList<Expression*>* args) { 3243 void FullCodeGenerator::EmitGetFromCache(ZoneList<Expression*>* args) {
3152 ASSERT_EQ(2, args->length()); 3244 ASSERT_EQ(2, args->length());
3153 3245
3154 ASSERT_NE(NULL, args->at(0)->AsLiteral()); 3246 ASSERT_NE(NULL, args->at(0)->AsLiteral());
3155 int cache_id = Smi::cast(*(args->at(0)->AsLiteral()->handle()))->value(); 3247 int cache_id = Smi::cast(*(args->at(0)->AsLiteral()->handle()))->value();
3156 3248
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
3222 __ mov(tmp, FieldOperand(left, JSRegExp::kDataOffset)); 3314 __ mov(tmp, FieldOperand(left, JSRegExp::kDataOffset));
3223 __ cmp(tmp, FieldOperand(right, JSRegExp::kDataOffset)); 3315 __ cmp(tmp, FieldOperand(right, JSRegExp::kDataOffset));
3224 __ j(equal, &ok); 3316 __ j(equal, &ok);
3225 __ bind(&fail); 3317 __ bind(&fail);
3226 __ mov(eax, Immediate(isolate()->factory()->false_value())); 3318 __ mov(eax, Immediate(isolate()->factory()->false_value()));
3227 __ jmp(&done); 3319 __ jmp(&done);
3228 __ bind(&ok); 3320 __ bind(&ok);
3229 __ mov(eax, Immediate(isolate()->factory()->true_value())); 3321 __ mov(eax, Immediate(isolate()->factory()->true_value()));
3230 __ bind(&done); 3322 __ bind(&done);
3231 3323
3324 decrement_stack_height();
3232 context()->Plug(eax); 3325 context()->Plug(eax);
3233 } 3326 }
3234 3327
3235 3328
3236 void FullCodeGenerator::EmitHasCachedArrayIndex(ZoneList<Expression*>* args) { 3329 void FullCodeGenerator::EmitHasCachedArrayIndex(ZoneList<Expression*>* args) {
3237 ASSERT(args->length() == 1); 3330 ASSERT(args->length() == 1);
3238 3331
3239 VisitForAccumulatorValue(args->at(0)); 3332 VisitForAccumulatorValue(args->at(0));
3240 3333
3241 if (FLAG_debug_code) { 3334 if (FLAG_debug_code) {
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after
3525 3618
3526 3619
3527 __ bind(&bailout); 3620 __ bind(&bailout);
3528 __ mov(result_operand, isolate()->factory()->undefined_value()); 3621 __ mov(result_operand, isolate()->factory()->undefined_value());
3529 __ bind(&done); 3622 __ bind(&done);
3530 __ mov(eax, result_operand); 3623 __ mov(eax, result_operand);
3531 // Drop temp values from the stack, and restore context register. 3624 // Drop temp values from the stack, and restore context register.
3532 __ add(Operand(esp), Immediate(3 * kPointerSize)); 3625 __ add(Operand(esp), Immediate(3 * kPointerSize));
3533 3626
3534 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 3627 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
3628 decrement_stack_height();
3535 context()->Plug(eax); 3629 context()->Plug(eax);
3536 } 3630 }
3537 3631
3538 3632
3539 void FullCodeGenerator::EmitIsNativeOrStrictMode(ZoneList<Expression*>* args) { 3633 void FullCodeGenerator::EmitIsNativeOrStrictMode(ZoneList<Expression*>* args) {
3540 ASSERT(args->length() == 1); 3634 ASSERT(args->length() == 1);
3541 3635
3542 // Load the function into eax. 3636 // Load the function into eax.
3543 VisitForAccumulatorValue(args->at(0)); 3637 VisitForAccumulatorValue(args->at(0));
3544 3638
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
3577 return; 3671 return;
3578 } 3672 }
3579 3673
3580 Comment cmnt(masm_, "[ CallRuntime"); 3674 Comment cmnt(masm_, "[ CallRuntime");
3581 ZoneList<Expression*>* args = expr->arguments(); 3675 ZoneList<Expression*>* args = expr->arguments();
3582 3676
3583 if (expr->is_jsruntime()) { 3677 if (expr->is_jsruntime()) {
3584 // Prepare for calling JS runtime function. 3678 // Prepare for calling JS runtime function.
3585 __ mov(eax, GlobalObjectOperand()); 3679 __ mov(eax, GlobalObjectOperand());
3586 __ push(FieldOperand(eax, GlobalObject::kBuiltinsOffset)); 3680 __ push(FieldOperand(eax, GlobalObject::kBuiltinsOffset));
3681 increment_stack_height();
3587 } 3682 }
3588 3683
3589 // Push the arguments ("left-to-right"). 3684 // Push the arguments ("left-to-right").
3590 int arg_count = args->length(); 3685 int arg_count = args->length();
3591 for (int i = 0; i < arg_count; i++) { 3686 for (int i = 0; i < arg_count; i++) {
3592 VisitForStackValue(args->at(i)); 3687 VisitForStackValue(args->at(i));
3593 } 3688 }
3594 3689
3595 if (expr->is_jsruntime()) { 3690 if (expr->is_jsruntime()) {
3596 // Call the JS runtime function via a call IC. 3691 // Call the JS runtime function via a call IC.
3597 __ Set(ecx, Immediate(expr->name())); 3692 __ Set(ecx, Immediate(expr->name()));
3598 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; 3693 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
3599 RelocInfo::Mode mode = RelocInfo::CODE_TARGET; 3694 RelocInfo::Mode mode = RelocInfo::CODE_TARGET;
3600 Handle<Code> ic = isolate()->stub_cache()->ComputeCallInitialize( 3695 Handle<Code> ic = isolate()->stub_cache()->ComputeCallInitialize(
3601 arg_count, in_loop, mode); 3696 arg_count, in_loop, mode);
3602 __ call(ic, mode, expr->id()); 3697 __ call(ic, mode, expr->id());
3603 // Restore context register. 3698 // Restore context register.
3604 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 3699 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
3605 } else { 3700 } else {
3606 // Call the C runtime function. 3701 // Call the C runtime function.
3607 __ CallRuntime(expr->function(), arg_count); 3702 __ CallRuntime(expr->function(), arg_count);
3608 } 3703 }
3704 decrement_stack_height(arg_count);
3705 if (expr->is_jsruntime()) {
3706 decrement_stack_height();
3707 }
3708
3609 context()->Plug(eax); 3709 context()->Plug(eax);
3610 } 3710 }
3611 3711
3612 3712
3613 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { 3713 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
3614 switch (expr->op()) { 3714 switch (expr->op()) {
3615 case Token::DELETE: { 3715 case Token::DELETE: {
3616 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); 3716 Comment cmnt(masm_, "[ UnaryOperation (DELETE)");
3617 Property* prop = expr->expression()->AsProperty(); 3717 Property* prop = expr->expression()->AsProperty();
3618 Variable* var = expr->expression()->AsVariableProxy()->AsVariable(); 3718 Variable* var = expr->expression()->AsVariableProxy()->AsVariable();
3619 3719
3620 if (prop != NULL) { 3720 if (prop != NULL) {
3621 if (prop->is_synthetic()) { 3721 if (prop->is_synthetic()) {
3622 // Result of deleting parameters is false, even when they rewrite 3722 // Result of deleting parameters is false, even when they rewrite
3623 // to accesses on the arguments object. 3723 // to accesses on the arguments object.
3624 context()->Plug(false); 3724 context()->Plug(false);
3625 } else { 3725 } else {
3626 VisitForStackValue(prop->obj()); 3726 VisitForStackValue(prop->obj());
3627 VisitForStackValue(prop->key()); 3727 VisitForStackValue(prop->key());
3628 __ push(Immediate(Smi::FromInt(strict_mode_flag()))); 3728 __ push(Immediate(Smi::FromInt(strict_mode_flag())));
3629 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); 3729 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
3730 decrement_stack_height(2);
3630 context()->Plug(eax); 3731 context()->Plug(eax);
3631 } 3732 }
3632 } else if (var != NULL) { 3733 } else if (var != NULL) {
3633 // Delete of an unqualified identifier is disallowed in strict mode 3734 // Delete of an unqualified identifier is disallowed in strict mode
3634 // but "delete this" is. 3735 // but "delete this" is.
3635 ASSERT(strict_mode_flag() == kNonStrictMode || var->is_this()); 3736 ASSERT(strict_mode_flag() == kNonStrictMode || var->is_this());
3636 if (var->is_global()) { 3737 if (var->is_global()) {
3637 __ push(GlobalObjectOperand()); 3738 __ push(GlobalObjectOperand());
3638 __ push(Immediate(var->name())); 3739 __ push(Immediate(var->name()));
3639 __ push(Immediate(Smi::FromInt(kNonStrictMode))); 3740 __ push(Immediate(Smi::FromInt(kNonStrictMode)));
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
3689 } 3790 }
3690 break; 3791 break;
3691 } 3792 }
3692 3793
3693 case Token::TYPEOF: { 3794 case Token::TYPEOF: {
3694 Comment cmnt(masm_, "[ UnaryOperation (TYPEOF)"); 3795 Comment cmnt(masm_, "[ UnaryOperation (TYPEOF)");
3695 { StackValueContext context(this); 3796 { StackValueContext context(this);
3696 VisitForTypeofValue(expr->expression()); 3797 VisitForTypeofValue(expr->expression());
3697 } 3798 }
3698 __ CallRuntime(Runtime::kTypeof, 1); 3799 __ CallRuntime(Runtime::kTypeof, 1);
3800 decrement_stack_height();
3699 context()->Plug(eax); 3801 context()->Plug(eax);
3700 break; 3802 break;
3701 } 3803 }
3702 3804
3703 case Token::ADD: { 3805 case Token::ADD: {
3704 Comment cmt(masm_, "[ UnaryOperation (ADD)"); 3806 Comment cmt(masm_, "[ UnaryOperation (ADD)");
3705 VisitForAccumulatorValue(expr->expression()); 3807 VisitForAccumulatorValue(expr->expression());
3706 Label no_conversion; 3808 Label no_conversion;
3707 __ JumpIfSmi(result_register(), &no_conversion); 3809 __ JumpIfSmi(result_register(), &no_conversion);
3708 ToNumberStub convert_stub; 3810 ToNumberStub convert_stub;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
3743 } 3845 }
3744 3846
3745 3847
3746 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { 3848 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
3747 Comment cmnt(masm_, "[ CountOperation"); 3849 Comment cmnt(masm_, "[ CountOperation");
3748 SetSourcePosition(expr->position()); 3850 SetSourcePosition(expr->position());
3749 3851
3750 // Invalid left-hand sides are rewritten to have a 'throw ReferenceError' 3852 // Invalid left-hand sides are rewritten to have a 'throw ReferenceError'
3751 // as the left-hand side. 3853 // as the left-hand side.
3752 if (!expr->expression()->IsValidLeftHandSide()) { 3854 if (!expr->expression()->IsValidLeftHandSide()) {
3753 VisitForEffect(expr->expression()); 3855 ASSERT(expr->expression()->AsThrow() != NULL);
3856 VisitInCurrentContext(expr->expression());
3857 // Visiting Throw does not plug the context.
3858 context()->Plug(eax);
3754 return; 3859 return;
3755 } 3860 }
3756 3861
3757 // Expression can only be a property, a global or a (parameter or local) 3862 // Expression can only be a property, a global or a (parameter or local)
3758 // slot. 3863 // slot.
3759 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; 3864 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
3760 LhsKind assign_type = VARIABLE; 3865 LhsKind assign_type = VARIABLE;
3761 Property* prop = expr->expression()->AsProperty(); 3866 Property* prop = expr->expression()->AsProperty();
3762 // In case of a property we use the uninitialized expression context 3867 // In case of a property we use the uninitialized expression context
3763 // of the key to detect a named property. 3868 // of the key to detect a named property.
3764 if (prop != NULL) { 3869 if (prop != NULL) {
3765 assign_type = 3870 assign_type =
3766 (prop->key()->IsPropertyName()) ? NAMED_PROPERTY : KEYED_PROPERTY; 3871 (prop->key()->IsPropertyName()) ? NAMED_PROPERTY : KEYED_PROPERTY;
3767 } 3872 }
3768 3873
3769 // Evaluate expression and get value. 3874 // Evaluate expression and get value.
3770 if (assign_type == VARIABLE) { 3875 if (assign_type == VARIABLE) {
3771 ASSERT(expr->expression()->AsVariableProxy()->var() != NULL); 3876 ASSERT(expr->expression()->AsVariableProxy()->var() != NULL);
3772 AccumulatorValueContext context(this); 3877 AccumulatorValueContext context(this);
3773 EmitVariableLoad(expr->expression()->AsVariableProxy()); 3878 EmitVariableLoad(expr->expression()->AsVariableProxy());
3774 } else { 3879 } else {
3775 // Reserve space for result of postfix operation. 3880 // Reserve space for result of postfix operation.
3776 if (expr->is_postfix() && !context()->IsEffect()) { 3881 if (expr->is_postfix() && !context()->IsEffect()) {
3777 __ push(Immediate(Smi::FromInt(0))); 3882 __ push(Immediate(Smi::FromInt(0)));
3883 increment_stack_height();
3778 } 3884 }
3779 if (assign_type == NAMED_PROPERTY) { 3885 if (assign_type == NAMED_PROPERTY) {
3780 // Put the object both on the stack and in the accumulator. 3886 // Put the object both on the stack and in the accumulator.
3781 VisitForAccumulatorValue(prop->obj()); 3887 VisitForAccumulatorValue(prop->obj());
3782 __ push(eax); 3888 __ push(eax);
3889 increment_stack_height();
3783 EmitNamedPropertyLoad(prop); 3890 EmitNamedPropertyLoad(prop);
3784 } else { 3891 } else {
3785 VisitForStackValue(prop->obj()); 3892 VisitForStackValue(prop->obj());
3786 VisitForAccumulatorValue(prop->key()); 3893 VisitForAccumulatorValue(prop->key());
3787 __ mov(edx, Operand(esp, 0)); 3894 __ mov(edx, Operand(esp, 0));
3788 __ push(eax); 3895 __ push(eax);
3896 increment_stack_height();
3789 EmitKeyedPropertyLoad(prop); 3897 EmitKeyedPropertyLoad(prop);
3790 } 3898 }
3791 } 3899 }
3792 3900
3793 // We need a second deoptimization point after loading the value 3901 // We need a second deoptimization point after loading the value
3794 // in case evaluating the property load my have a side effect. 3902 // in case evaluating the property load my have a side effect.
3795 if (assign_type == VARIABLE) { 3903 if (assign_type == VARIABLE) {
3796 PrepareForBailout(expr->expression(), TOS_REG); 3904 PrepareForBailout(expr->expression(), TOS_REG);
3797 } else { 3905 } else {
3798 PrepareForBailoutForId(expr->CountId(), TOS_REG); 3906 PrepareForBailoutForId(expr->CountId(), TOS_REG);
(...skipping 10 matching lines...) Expand all
3809 3917
3810 // Save result for postfix expressions. 3918 // Save result for postfix expressions.
3811 if (expr->is_postfix()) { 3919 if (expr->is_postfix()) {
3812 if (!context()->IsEffect()) { 3920 if (!context()->IsEffect()) {
3813 // Save the result on the stack. If we have a named or keyed property 3921 // Save the result on the stack. If we have a named or keyed property
3814 // we store the result under the receiver that is currently on top 3922 // we store the result under the receiver that is currently on top
3815 // of the stack. 3923 // of the stack.
3816 switch (assign_type) { 3924 switch (assign_type) {
3817 case VARIABLE: 3925 case VARIABLE:
3818 __ push(eax); 3926 __ push(eax);
3927 increment_stack_height();
3819 break; 3928 break;
3820 case NAMED_PROPERTY: 3929 case NAMED_PROPERTY:
3821 __ mov(Operand(esp, kPointerSize), eax); 3930 __ mov(Operand(esp, kPointerSize), eax);
3822 break; 3931 break;
3823 case KEYED_PROPERTY: 3932 case KEYED_PROPERTY:
3824 __ mov(Operand(esp, 2 * kPointerSize), eax); 3933 __ mov(Operand(esp, 2 * kPointerSize), eax);
3825 break; 3934 break;
3826 } 3935 }
3827 } 3936 }
3828 } 3937 }
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
3882 // Perform the assignment as if via '='. 3991 // Perform the assignment as if via '='.
3883 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 3992 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
3884 Token::ASSIGN); 3993 Token::ASSIGN);
3885 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3994 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3886 context()->Plug(eax); 3995 context()->Plug(eax);
3887 } 3996 }
3888 break; 3997 break;
3889 case NAMED_PROPERTY: { 3998 case NAMED_PROPERTY: {
3890 __ mov(ecx, prop->key()->AsLiteral()->handle()); 3999 __ mov(ecx, prop->key()->AsLiteral()->handle());
3891 __ pop(edx); 4000 __ pop(edx);
4001 decrement_stack_height();
3892 Handle<Code> ic = is_strict_mode() 4002 Handle<Code> ic = is_strict_mode()
3893 ? isolate()->builtins()->StoreIC_Initialize_Strict() 4003 ? isolate()->builtins()->StoreIC_Initialize_Strict()
3894 : isolate()->builtins()->StoreIC_Initialize(); 4004 : isolate()->builtins()->StoreIC_Initialize();
3895 __ call(ic, RelocInfo::CODE_TARGET, expr->id()); 4005 __ call(ic, RelocInfo::CODE_TARGET, expr->id());
3896 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4006 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3897 if (expr->is_postfix()) { 4007 if (expr->is_postfix()) {
3898 if (!context()->IsEffect()) { 4008 if (!context()->IsEffect()) {
3899 context()->PlugTOS(); 4009 context()->PlugTOS();
3900 } 4010 }
3901 } else { 4011 } else {
3902 context()->Plug(eax); 4012 context()->Plug(eax);
3903 } 4013 }
3904 break; 4014 break;
3905 } 4015 }
3906 case KEYED_PROPERTY: { 4016 case KEYED_PROPERTY: {
3907 __ pop(ecx); 4017 __ pop(ecx);
3908 __ pop(edx); 4018 __ pop(edx);
4019 decrement_stack_height();
4020 decrement_stack_height();
3909 Handle<Code> ic = is_strict_mode() 4021 Handle<Code> ic = is_strict_mode()
3910 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 4022 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
3911 : isolate()->builtins()->KeyedStoreIC_Initialize(); 4023 : isolate()->builtins()->KeyedStoreIC_Initialize();
3912 __ call(ic, RelocInfo::CODE_TARGET, expr->id()); 4024 __ call(ic, RelocInfo::CODE_TARGET, expr->id());
3913 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4025 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3914 if (expr->is_postfix()) { 4026 if (expr->is_postfix()) {
3915 // Result is on the stack 4027 // Result is on the stack
3916 if (!context()->IsEffect()) { 4028 if (!context()->IsEffect()) {
3917 context()->PlugTOS(); 4029 context()->PlugTOS();
3918 } 4030 }
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
4056 context()->Plug(if_true, if_false); 4168 context()->Plug(if_true, if_false);
4057 return; 4169 return;
4058 } 4170 }
4059 4171
4060 Token::Value op = expr->op(); 4172 Token::Value op = expr->op();
4061 VisitForStackValue(expr->left()); 4173 VisitForStackValue(expr->left());
4062 switch (expr->op()) { 4174 switch (expr->op()) {
4063 case Token::IN: 4175 case Token::IN:
4064 VisitForStackValue(expr->right()); 4176 VisitForStackValue(expr->right());
4065 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION); 4177 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION);
4178 decrement_stack_height(2);
4066 PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL); 4179 PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL);
4067 __ cmp(eax, isolate()->factory()->true_value()); 4180 __ cmp(eax, isolate()->factory()->true_value());
4068 Split(equal, if_true, if_false, fall_through); 4181 Split(equal, if_true, if_false, fall_through);
4069 break; 4182 break;
4070 4183
4071 case Token::INSTANCEOF: { 4184 case Token::INSTANCEOF: {
4072 VisitForStackValue(expr->right()); 4185 VisitForStackValue(expr->right());
4073 InstanceofStub stub(InstanceofStub::kNoFlags); 4186 InstanceofStub stub(InstanceofStub::kNoFlags);
4074 __ CallStub(&stub); 4187 __ CallStub(&stub);
4188 decrement_stack_height(2);
4075 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); 4189 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
4076 __ test(eax, Operand(eax)); 4190 __ test(eax, Operand(eax));
4077 // The stub returns 0 for true. 4191 // The stub returns 0 for true.
4078 Split(zero, if_true, if_false, fall_through); 4192 Split(zero, if_true, if_false, fall_through);
4079 break; 4193 break;
4080 } 4194 }
4081 4195
4082 default: { 4196 default: {
4083 VisitForAccumulatorValue(expr->right()); 4197 VisitForAccumulatorValue(expr->right());
4084 Condition cc = no_condition; 4198 Condition cc = no_condition;
(...skipping 24 matching lines...) Expand all
4109 break; 4223 break;
4110 case Token::GTE: 4224 case Token::GTE:
4111 cc = greater_equal; 4225 cc = greater_equal;
4112 __ pop(edx); 4226 __ pop(edx);
4113 break; 4227 break;
4114 case Token::IN: 4228 case Token::IN:
4115 case Token::INSTANCEOF: 4229 case Token::INSTANCEOF:
4116 default: 4230 default:
4117 UNREACHABLE(); 4231 UNREACHABLE();
4118 } 4232 }
4233 decrement_stack_height();
4119 4234
4120 bool inline_smi_code = ShouldInlineSmiCase(op); 4235 bool inline_smi_code = ShouldInlineSmiCase(op);
4121 JumpPatchSite patch_site(masm_); 4236 JumpPatchSite patch_site(masm_);
4122 if (inline_smi_code) { 4237 if (inline_smi_code) {
4123 Label slow_case; 4238 Label slow_case;
4124 __ mov(ecx, Operand(edx)); 4239 __ mov(ecx, Operand(edx));
4125 __ or_(ecx, Operand(eax)); 4240 __ or_(ecx, Operand(eax));
4126 patch_site.EmitJumpIfNotSmi(ecx, &slow_case, Label::kNear); 4241 patch_site.EmitJumpIfNotSmi(ecx, &slow_case, Label::kNear);
4127 __ cmp(edx, Operand(eax)); 4242 __ cmp(edx, Operand(eax));
4128 Split(cc, if_true, if_false, NULL); 4243 Split(cc, if_true, if_false, NULL);
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
4249 __ add(Operand(edx), Immediate(masm_->CodeObject())); 4364 __ add(Operand(edx), Immediate(masm_->CodeObject()));
4250 __ jmp(Operand(edx)); 4365 __ jmp(Operand(edx));
4251 } 4366 }
4252 4367
4253 4368
4254 #undef __ 4369 #undef __
4255 4370
4256 } } // namespace v8::internal 4371 } } // namespace v8::internal
4257 4372
4258 #endif // V8_TARGET_ARCH_IA32 4373 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/full-codegen.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698