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

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

Issue 7535004: Merge bleeding edge up to 8774 into the GC branch. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: 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/ia32/cpu-ia32.cc ('k') | src/ia32/lithium-codegen-ia32.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 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 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
352 #ifdef ENABLE_DEBUGGER_SUPPORT 357 #ifdef ENABLE_DEBUGGER_SUPPORT
353 // Check that the size of the code used for returning is large enough 358 // Check that the size of the code used for returning is large enough
354 // for the debugger's requirements. 359 // for the debugger's requirements.
355 ASSERT(Assembler::kJSReturnSequenceLength <= 360 ASSERT(Assembler::kJSReturnSequenceLength <=
356 masm_->SizeOfCodeGeneratedSince(&check_exit_codesize)); 361 masm_->SizeOfCodeGeneratedSince(&check_exit_codesize));
357 #endif 362 #endif
358 } 363 }
359 } 364 }
360 365
361 366
367 void FullCodeGenerator::verify_stack_height() {
368 ASSERT(FLAG_verify_stack_height);
369 __ sub(Operand(ebp), Immediate(kPointerSize * stack_height()));
370 __ cmp(ebp, Operand(esp));
371 __ Assert(equal, "Full codegen stack height not as expected.");
372 __ add(Operand(ebp), Immediate(kPointerSize * stack_height()));
373 }
374
375
362 void FullCodeGenerator::EffectContext::Plug(Slot* slot) const { 376 void FullCodeGenerator::EffectContext::Plug(Slot* slot) const {
363 } 377 }
364 378
365 379
366 void FullCodeGenerator::AccumulatorValueContext::Plug(Slot* slot) const { 380 void FullCodeGenerator::AccumulatorValueContext::Plug(Slot* slot) const {
367 MemOperand slot_operand = codegen()->EmitSlotSearch(slot, result_register()); 381 MemOperand slot_operand = codegen()->EmitSlotSearch(slot, result_register());
368 __ mov(result_register(), slot_operand); 382 __ mov(result_register(), slot_operand);
369 } 383 }
370 384
371 385
372 void FullCodeGenerator::StackValueContext::Plug(Slot* slot) const { 386 void FullCodeGenerator::StackValueContext::Plug(Slot* slot) const {
373 MemOperand slot_operand = codegen()->EmitSlotSearch(slot, result_register()); 387 MemOperand slot_operand = codegen()->EmitSlotSearch(slot, result_register());
374 // Memory operands can be pushed directly. 388 // Memory operands can be pushed directly.
375 __ push(slot_operand); 389 __ push(slot_operand);
390 codegen()->increment_stack_height();
376 } 391 }
377 392
378 393
379 void FullCodeGenerator::TestContext::Plug(Slot* slot) const { 394 void FullCodeGenerator::TestContext::Plug(Slot* slot) const {
380 // For simplicity we always test the accumulator register. 395 // For simplicity we always test the accumulator register.
381 codegen()->Move(result_register(), slot); 396 codegen()->Move(result_register(), slot);
382 codegen()->PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL); 397 codegen()->PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL);
383 codegen()->DoTest(this); 398 codegen()->DoTest(this);
384 } 399 }
385 400
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
419 } 434 }
420 } 435 }
421 436
422 437
423 void FullCodeGenerator::StackValueContext::Plug(Handle<Object> lit) const { 438 void FullCodeGenerator::StackValueContext::Plug(Handle<Object> lit) const {
424 if (lit->IsSmi()) { 439 if (lit->IsSmi()) {
425 __ SafePush(Immediate(lit)); 440 __ SafePush(Immediate(lit));
426 } else { 441 } else {
427 __ push(Immediate(lit)); 442 __ push(Immediate(lit));
428 } 443 }
444 codegen()->increment_stack_height();
429 } 445 }
430 446
431 447
432 void FullCodeGenerator::TestContext::Plug(Handle<Object> lit) const { 448 void FullCodeGenerator::TestContext::Plug(Handle<Object> lit) const {
433 codegen()->PrepareForBailoutBeforeSplit(TOS_REG, 449 codegen()->PrepareForBailoutBeforeSplit(TOS_REG,
434 true, 450 true,
435 true_label_, 451 true_label_,
436 false_label_); 452 false_label_);
437 ASSERT(!lit->IsUndetectableObject()); // There are no undetectable literals. 453 ASSERT(!lit->IsUndetectableObject()); // There are no undetectable literals.
438 if (lit->IsUndefined() || lit->IsNull() || lit->IsFalse()) { 454 if (lit->IsUndefined() || lit->IsNull() || lit->IsFalse()) {
(...skipping 17 matching lines...) Expand all
456 __ mov(result_register(), lit); 472 __ mov(result_register(), lit);
457 codegen()->DoTest(this); 473 codegen()->DoTest(this);
458 } 474 }
459 } 475 }
460 476
461 477
462 void FullCodeGenerator::EffectContext::DropAndPlug(int count, 478 void FullCodeGenerator::EffectContext::DropAndPlug(int count,
463 Register reg) const { 479 Register reg) const {
464 ASSERT(count > 0); 480 ASSERT(count > 0);
465 __ Drop(count); 481 __ Drop(count);
482 codegen()->decrement_stack_height(count);
466 } 483 }
467 484
468 485
469 void FullCodeGenerator::AccumulatorValueContext::DropAndPlug( 486 void FullCodeGenerator::AccumulatorValueContext::DropAndPlug(
470 int count, 487 int count,
471 Register reg) const { 488 Register reg) const {
472 ASSERT(count > 0); 489 ASSERT(count > 0);
473 __ Drop(count); 490 __ Drop(count);
474 __ Move(result_register(), reg); 491 __ Move(result_register(), reg);
492 codegen()->decrement_stack_height(count);
475 } 493 }
476 494
477 495
478 void FullCodeGenerator::StackValueContext::DropAndPlug(int count, 496 void FullCodeGenerator::StackValueContext::DropAndPlug(int count,
479 Register reg) const { 497 Register reg) const {
480 ASSERT(count > 0); 498 ASSERT(count > 0);
481 if (count > 1) __ Drop(count - 1); 499 if (count > 1) __ Drop(count - 1);
482 __ mov(Operand(esp, 0), reg); 500 __ mov(Operand(esp, 0), reg);
501 codegen()->decrement_stack_height(count - 1);
483 } 502 }
484 503
485 504
486 void FullCodeGenerator::TestContext::DropAndPlug(int count, 505 void FullCodeGenerator::TestContext::DropAndPlug(int count,
487 Register reg) const { 506 Register reg) const {
488 ASSERT(count > 0); 507 ASSERT(count > 0);
489 // For simplicity we always test the accumulator register. 508 // For simplicity we always test the accumulator register.
490 __ Drop(count); 509 __ Drop(count);
491 __ Move(result_register(), reg); 510 __ Move(result_register(), reg);
492 codegen()->PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL); 511 codegen()->PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL);
493 codegen()->DoTest(this); 512 codegen()->DoTest(this);
513 codegen()->decrement_stack_height(count);
494 } 514 }
495 515
496 516
497 void FullCodeGenerator::EffectContext::Plug(Label* materialize_true, 517 void FullCodeGenerator::EffectContext::Plug(Label* materialize_true,
498 Label* materialize_false) const { 518 Label* materialize_false) const {
499 ASSERT(materialize_true == materialize_false); 519 ASSERT(materialize_true == materialize_false);
500 __ bind(materialize_true); 520 __ bind(materialize_true);
501 } 521 }
502 522
503 523
(...skipping 13 matching lines...) Expand all
517 void FullCodeGenerator::StackValueContext::Plug( 537 void FullCodeGenerator::StackValueContext::Plug(
518 Label* materialize_true, 538 Label* materialize_true,
519 Label* materialize_false) const { 539 Label* materialize_false) const {
520 Label done; 540 Label done;
521 __ bind(materialize_true); 541 __ bind(materialize_true);
522 __ push(Immediate(isolate()->factory()->true_value())); 542 __ push(Immediate(isolate()->factory()->true_value()));
523 __ jmp(&done, Label::kNear); 543 __ jmp(&done, Label::kNear);
524 __ bind(materialize_false); 544 __ bind(materialize_false);
525 __ push(Immediate(isolate()->factory()->false_value())); 545 __ push(Immediate(isolate()->factory()->false_value()));
526 __ bind(&done); 546 __ bind(&done);
547 codegen()->increment_stack_height();
527 } 548 }
528 549
529 550
530 void FullCodeGenerator::TestContext::Plug(Label* materialize_true, 551 void FullCodeGenerator::TestContext::Plug(Label* materialize_true,
531 Label* materialize_false) const { 552 Label* materialize_false) const {
532 ASSERT(materialize_true == true_label_); 553 ASSERT(materialize_true == true_label_);
533 ASSERT(materialize_false == false_label_); 554 ASSERT(materialize_false == false_label_);
534 } 555 }
535 556
536 557
537 void FullCodeGenerator::EffectContext::Plug(bool flag) const { 558 void FullCodeGenerator::EffectContext::Plug(bool flag) const {
538 } 559 }
539 560
540 561
541 void FullCodeGenerator::AccumulatorValueContext::Plug(bool flag) const { 562 void FullCodeGenerator::AccumulatorValueContext::Plug(bool flag) const {
542 Handle<Object> value = flag 563 Handle<Object> value = flag
543 ? isolate()->factory()->true_value() 564 ? isolate()->factory()->true_value()
544 : isolate()->factory()->false_value(); 565 : isolate()->factory()->false_value();
545 __ mov(result_register(), value); 566 __ mov(result_register(), value);
546 } 567 }
547 568
548 569
549 void FullCodeGenerator::StackValueContext::Plug(bool flag) const { 570 void FullCodeGenerator::StackValueContext::Plug(bool flag) const {
550 Handle<Object> value = flag 571 Handle<Object> value = flag
551 ? isolate()->factory()->true_value() 572 ? isolate()->factory()->true_value()
552 : isolate()->factory()->false_value(); 573 : isolate()->factory()->false_value();
553 __ push(Immediate(value)); 574 __ push(Immediate(value));
575 codegen()->increment_stack_height();
554 } 576 }
555 577
556 578
557 void FullCodeGenerator::TestContext::Plug(bool flag) const { 579 void FullCodeGenerator::TestContext::Plug(bool flag) const {
558 codegen()->PrepareForBailoutBeforeSplit(TOS_REG, 580 codegen()->PrepareForBailoutBeforeSplit(TOS_REG,
559 true, 581 true,
560 true_label_, 582 true_label_,
561 false_label_); 583 false_label_);
562 if (flag) { 584 if (flag) {
563 if (true_label_ != fall_through_) __ jmp(true_label_); 585 if (true_label_ != fall_through_) __ jmp(true_label_);
564 } else { 586 } else {
565 if (false_label_ != fall_through_) __ jmp(false_label_); 587 if (false_label_ != fall_through_) __ jmp(false_label_);
566 } 588 }
567 } 589 }
568 590
569 591
570 void FullCodeGenerator::DoTest(Expression* condition, 592 void FullCodeGenerator::DoTest(Expression* condition,
571 Label* if_true, 593 Label* if_true,
572 Label* if_false, 594 Label* if_false,
573 Label* fall_through) { 595 Label* fall_through) {
574 ToBooleanStub stub(result_register()); 596 ToBooleanStub stub(result_register());
575 __ push(result_register()); 597 __ push(result_register());
576 __ CallStub(&stub); 598 __ CallStub(&stub, condition->test_id());
577 __ test(result_register(), Operand(result_register())); 599 __ test(result_register(), Operand(result_register()));
578 // The stub returns nonzero for true. 600 // The stub returns nonzero for true.
579 Split(not_zero, if_true, if_false, fall_through); 601 Split(not_zero, if_true, if_false, fall_through);
580 } 602 }
581 603
582 604
583 void FullCodeGenerator::Split(Condition cc, 605 void FullCodeGenerator::Split(Condition cc,
584 Label* if_true, 606 Label* if_true,
585 Label* if_false, 607 Label* if_false,
586 Label* fall_through) { 608 Label* fall_through) {
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
724 __ push(esi); 746 __ push(esi);
725 __ push(Immediate(variable->name())); 747 __ push(Immediate(variable->name()));
726 // Declaration nodes are always introduced in one of two modes. 748 // Declaration nodes are always introduced in one of two modes.
727 ASSERT(mode == Variable::VAR || mode == Variable::CONST); 749 ASSERT(mode == Variable::VAR || mode == Variable::CONST);
728 PropertyAttributes attr = (mode == Variable::VAR) ? NONE : READ_ONLY; 750 PropertyAttributes attr = (mode == Variable::VAR) ? NONE : READ_ONLY;
729 __ push(Immediate(Smi::FromInt(attr))); 751 __ push(Immediate(Smi::FromInt(attr)));
730 // Push initial value, if any. 752 // Push initial value, if any.
731 // Note: For variables we must not push an initial value (such as 753 // Note: For variables we must not push an initial value (such as
732 // 'undefined') because we may have a (legal) redeclaration and we 754 // 'undefined') because we may have a (legal) redeclaration and we
733 // must not destroy the current value. 755 // must not destroy the current value.
756 increment_stack_height(3);
734 if (mode == Variable::CONST) { 757 if (mode == Variable::CONST) {
735 __ push(Immediate(isolate()->factory()->the_hole_value())); 758 __ push(Immediate(isolate()->factory()->the_hole_value()));
759 increment_stack_height();
736 } else if (function != NULL) { 760 } else if (function != NULL) {
737 VisitForStackValue(function); 761 VisitForStackValue(function);
738 } else { 762 } else {
739 __ push(Immediate(Smi::FromInt(0))); // No initial value! 763 __ push(Immediate(Smi::FromInt(0))); // No initial value!
764 increment_stack_height();
740 } 765 }
741 __ CallRuntime(Runtime::kDeclareContextSlot, 4); 766 __ CallRuntime(Runtime::kDeclareContextSlot, 4);
767 decrement_stack_height(4);
742 break; 768 break;
743 } 769 }
744 } 770 }
745 771
746 } else if (prop != NULL) { 772 } else if (prop != NULL) {
747 // A const declaration aliasing a parameter is an illegal redeclaration. 773 // A const declaration aliasing a parameter is an illegal redeclaration.
748 ASSERT(mode != Variable::CONST); 774 ASSERT(mode != Variable::CONST);
749 if (function != NULL) { 775 if (function != NULL) {
750 // We are declaring a function that rewrites to a property. 776 // We are declaring a function that rewrites to a property.
751 // Use (keyed) IC to set the initial value. We cannot visit the 777 // Use (keyed) IC to set the initial value. We cannot visit the
752 // rewrite because it's shared and we risk recording duplicate AST 778 // rewrite because it's shared and we risk recording duplicate AST
753 // IDs for bailouts from optimized code. 779 // IDs for bailouts from optimized code.
754 ASSERT(prop->obj()->AsVariableProxy() != NULL); 780 ASSERT(prop->obj()->AsVariableProxy() != NULL);
755 { AccumulatorValueContext for_object(this); 781 { AccumulatorValueContext for_object(this);
756 EmitVariableLoad(prop->obj()->AsVariableProxy()->var()); 782 EmitVariableLoad(prop->obj()->AsVariableProxy());
757 } 783 }
758 784
759 __ push(eax); 785 __ push(eax);
786 increment_stack_height();
760 VisitForAccumulatorValue(function); 787 VisitForAccumulatorValue(function);
761 __ pop(edx); 788 __ pop(edx);
789 decrement_stack_height();
762 790
763 ASSERT(prop->key()->AsLiteral() != NULL && 791 ASSERT(prop->key()->AsLiteral() != NULL &&
764 prop->key()->AsLiteral()->handle()->IsSmi()); 792 prop->key()->AsLiteral()->handle()->IsSmi());
765 __ SafeSet(ecx, Immediate(prop->key()->AsLiteral()->handle())); 793 __ SafeSet(ecx, Immediate(prop->key()->AsLiteral()->handle()));
766 794
767 Handle<Code> ic = is_strict_mode() 795 Handle<Code> ic = is_strict_mode()
768 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 796 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
769 : isolate()->builtins()->KeyedStoreIC_Initialize(); 797 : isolate()->builtins()->KeyedStoreIC_Initialize();
770 __ call(ic); 798 __ call(ic);
771 } 799 }
(...skipping 15 matching lines...) Expand all
787 __ CallRuntime(Runtime::kDeclareGlobals, 4); 815 __ CallRuntime(Runtime::kDeclareGlobals, 4);
788 // Return value is ignored. 816 // Return value is ignored.
789 } 817 }
790 818
791 819
792 void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { 820 void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
793 Comment cmnt(masm_, "[ SwitchStatement"); 821 Comment cmnt(masm_, "[ SwitchStatement");
794 Breakable nested_statement(this, stmt); 822 Breakable nested_statement(this, stmt);
795 SetStatementPosition(stmt); 823 SetStatementPosition(stmt);
796 824
825 int switch_clause_stack_height = stack_height();
797 // Keep the switch value on the stack until a case matches. 826 // Keep the switch value on the stack until a case matches.
798 VisitForStackValue(stmt->tag()); 827 VisitForStackValue(stmt->tag());
799 PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS); 828 PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS);
800 829
801 ZoneList<CaseClause*>* clauses = stmt->cases(); 830 ZoneList<CaseClause*>* clauses = stmt->cases();
802 CaseClause* default_clause = NULL; // Can occur anywhere in the list. 831 CaseClause* default_clause = NULL; // Can occur anywhere in the list.
803 832
804 Label next_test; // Recycled for each test. 833 Label next_test; // Recycled for each test.
805 // Compile all the tests with branches to their bodies. 834 // Compile all the tests with branches to their bodies.
806 for (int i = 0; i < clauses->length(); i++) { 835 for (int i = 0; i < clauses->length(); i++) {
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
851 // Discard the test value and jump to the default if present, otherwise to 880 // Discard the test value and jump to the default if present, otherwise to
852 // the end of the statement. 881 // the end of the statement.
853 __ bind(&next_test); 882 __ bind(&next_test);
854 __ Drop(1); // Switch value is no longer needed. 883 __ Drop(1); // Switch value is no longer needed.
855 if (default_clause == NULL) { 884 if (default_clause == NULL) {
856 __ jmp(nested_statement.break_target()); 885 __ jmp(nested_statement.break_target());
857 } else { 886 } else {
858 __ jmp(default_clause->body_target()); 887 __ jmp(default_clause->body_target());
859 } 888 }
860 889
890 set_stack_height(switch_clause_stack_height);
861 // Compile all the case bodies. 891 // Compile all the case bodies.
862 for (int i = 0; i < clauses->length(); i++) { 892 for (int i = 0; i < clauses->length(); i++) {
863 Comment cmnt(masm_, "[ Case body"); 893 Comment cmnt(masm_, "[ Case body");
864 CaseClause* clause = clauses->at(i); 894 CaseClause* clause = clauses->at(i);
865 __ bind(clause->body_target()); 895 __ bind(clause->body_target());
866 PrepareForBailoutForId(clause->EntryId(), NO_REGISTERS); 896 PrepareForBailoutForId(clause->EntryId(), NO_REGISTERS);
867 VisitStatements(clause->statements()); 897 VisitStatements(clause->statements());
868 } 898 }
869 899
870 __ bind(nested_statement.break_target()); 900 __ bind(nested_statement.break_target());
(...skipping 21 matching lines...) Expand all
892 // Convert the object to a JS object. 922 // Convert the object to a JS object.
893 Label convert, done_convert; 923 Label convert, done_convert;
894 __ JumpIfSmi(eax, &convert, Label::kNear); 924 __ JumpIfSmi(eax, &convert, Label::kNear);
895 __ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, ecx); 925 __ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, ecx);
896 __ j(above_equal, &done_convert, Label::kNear); 926 __ j(above_equal, &done_convert, Label::kNear);
897 __ bind(&convert); 927 __ bind(&convert);
898 __ push(eax); 928 __ push(eax);
899 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION); 929 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
900 __ bind(&done_convert); 930 __ bind(&done_convert);
901 __ push(eax); 931 __ push(eax);
932 increment_stack_height();
902 933
903 // Check cache validity in generated code. This is a fast case for 934 // Check cache validity in generated code. This is a fast case for
904 // the JSObject::IsSimpleEnum cache validity checks. If we cannot 935 // the JSObject::IsSimpleEnum cache validity checks. If we cannot
905 // guarantee cache validity, call the runtime system to check cache 936 // guarantee cache validity, call the runtime system to check cache
906 // validity or get the property names in a fixed array. 937 // validity or get the property names in a fixed array.
907 Label next, call_runtime; 938 Label next, call_runtime;
908 __ mov(ecx, eax); 939 __ mov(ecx, eax);
909 __ bind(&next); 940 __ bind(&next);
910 941
911 // Check that there are no elements. Register ecx contains the 942 // Check that there are no elements. Register ecx contains the
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
975 __ jmp(&loop); 1006 __ jmp(&loop);
976 1007
977 // We got a fixed array in register eax. Iterate through that. 1008 // We got a fixed array in register eax. Iterate through that.
978 __ bind(&fixed_array); 1009 __ bind(&fixed_array);
979 __ push(Immediate(Smi::FromInt(0))); // Map (0) - force slow check. 1010 __ push(Immediate(Smi::FromInt(0))); // Map (0) - force slow check.
980 __ push(eax); 1011 __ push(eax);
981 __ mov(eax, FieldOperand(eax, FixedArray::kLengthOffset)); 1012 __ mov(eax, FieldOperand(eax, FixedArray::kLengthOffset));
982 __ push(eax); // Fixed array length (as smi). 1013 __ push(eax); // Fixed array length (as smi).
983 __ push(Immediate(Smi::FromInt(0))); // Initial index. 1014 __ push(Immediate(Smi::FromInt(0))); // Initial index.
984 1015
1016 increment_stack_height(4);
985 // Generate code for doing the condition check. 1017 // Generate code for doing the condition check.
986 __ bind(&loop); 1018 __ bind(&loop);
987 __ mov(eax, Operand(esp, 0 * kPointerSize)); // Get the current index. 1019 __ mov(eax, Operand(esp, 0 * kPointerSize)); // Get the current index.
988 __ cmp(eax, Operand(esp, 1 * kPointerSize)); // Compare to the array length. 1020 __ cmp(eax, Operand(esp, 1 * kPointerSize)); // Compare to the array length.
989 __ j(above_equal, loop_statement.break_target()); 1021 __ j(above_equal, loop_statement.break_target());
990 1022
991 // Get the current entry of the array into register ebx. 1023 // Get the current entry of the array into register ebx.
992 __ mov(ebx, Operand(esp, 2 * kPointerSize)); 1024 __ mov(ebx, Operand(esp, 2 * kPointerSize));
993 __ mov(ebx, FieldOperand(ebx, eax, times_2, FixedArray::kHeaderSize)); 1025 __ mov(ebx, FieldOperand(ebx, eax, times_2, FixedArray::kHeaderSize));
994 1026
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1030 __ bind(loop_statement.continue_target()); 1062 __ bind(loop_statement.continue_target());
1031 __ add(Operand(esp, 0 * kPointerSize), Immediate(Smi::FromInt(1))); 1063 __ add(Operand(esp, 0 * kPointerSize), Immediate(Smi::FromInt(1)));
1032 1064
1033 EmitStackCheck(stmt); 1065 EmitStackCheck(stmt);
1034 __ jmp(&loop); 1066 __ jmp(&loop);
1035 1067
1036 // Remove the pointers stored on the stack. 1068 // Remove the pointers stored on the stack.
1037 __ bind(loop_statement.break_target()); 1069 __ bind(loop_statement.break_target());
1038 __ add(Operand(esp), Immediate(5 * kPointerSize)); 1070 __ add(Operand(esp), Immediate(5 * kPointerSize));
1039 1071
1072 decrement_stack_height(5);
1040 // Exit and decrement the loop depth. 1073 // Exit and decrement the loop depth.
1041 __ bind(&exit); 1074 __ bind(&exit);
1042 decrement_loop_depth(); 1075 decrement_loop_depth();
1043 } 1076 }
1044 1077
1045 1078
1046 void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info, 1079 void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info,
1047 bool pretenure) { 1080 bool pretenure) {
1048 // Use the fast case closure allocation code that allocates in new 1081 // Use the fast case closure allocation code that allocates in new
1049 // space for nested functions that don't need literals cloning. If 1082 // space for nested functions that don't need literals cloning. If
(...skipping 16 matching lines...) Expand all
1066 ? isolate()->factory()->true_value() 1099 ? isolate()->factory()->true_value()
1067 : isolate()->factory()->false_value())); 1100 : isolate()->factory()->false_value()));
1068 __ CallRuntime(Runtime::kNewClosure, 3); 1101 __ CallRuntime(Runtime::kNewClosure, 3);
1069 } 1102 }
1070 context()->Plug(eax); 1103 context()->Plug(eax);
1071 } 1104 }
1072 1105
1073 1106
1074 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) { 1107 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
1075 Comment cmnt(masm_, "[ VariableProxy"); 1108 Comment cmnt(masm_, "[ VariableProxy");
1076 EmitVariableLoad(expr->var()); 1109 EmitVariableLoad(expr);
1077 } 1110 }
1078 1111
1079 1112
1080 void FullCodeGenerator::EmitLoadGlobalSlotCheckExtensions( 1113 void FullCodeGenerator::EmitLoadGlobalSlotCheckExtensions(
1081 Slot* slot, 1114 Slot* slot,
1082 TypeofState typeof_state, 1115 TypeofState typeof_state,
1083 Label* slow) { 1116 Label* slow) {
1084 Register context = esi; 1117 Register context = esi;
1085 Register temp = edx; 1118 Register temp = edx;
1086 1119
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
1216 isolate()->builtins()->KeyedLoadIC_Initialize(); 1249 isolate()->builtins()->KeyedLoadIC_Initialize();
1217 __ call(ic, RelocInfo::CODE_TARGET, GetPropertyId(property)); 1250 __ call(ic, RelocInfo::CODE_TARGET, GetPropertyId(property));
1218 __ jmp(done); 1251 __ jmp(done);
1219 } 1252 }
1220 } 1253 }
1221 } 1254 }
1222 } 1255 }
1223 } 1256 }
1224 1257
1225 1258
1226 void FullCodeGenerator::EmitVariableLoad(Variable* var) { 1259 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) {
1260 // Record position before possible IC call.
1261 SetSourcePosition(proxy->position());
1262 Variable* var = proxy->var();
1263
1227 // Three cases: non-this global variables, lookup slots, and all other 1264 // Three cases: non-this global variables, lookup slots, and all other
1228 // types of slots. 1265 // types of slots.
1229 Slot* slot = var->AsSlot(); 1266 Slot* slot = var->AsSlot();
1230 ASSERT((var->is_global() && !var->is_this()) == (slot == NULL)); 1267 ASSERT((var->is_global() && !var->is_this()) == (slot == NULL));
1231 1268
1232 if (slot == NULL) { 1269 if (slot == NULL) {
1233 Comment cmnt(masm_, "Global variable"); 1270 Comment cmnt(masm_, "Global variable");
1234 // Use inline caching. Variable name is passed in ecx and the global 1271 // Use inline caching. Variable name is passed in ecx and the global
1235 // object on the stack. 1272 // object on the stack.
1236 __ mov(eax, GlobalObjectOperand()); 1273 __ mov(eax, GlobalObjectOperand());
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
1361 1398
1362 for (int i = 0; i < expr->properties()->length(); i++) { 1399 for (int i = 0; i < expr->properties()->length(); i++) {
1363 ObjectLiteral::Property* property = expr->properties()->at(i); 1400 ObjectLiteral::Property* property = expr->properties()->at(i);
1364 if (property->IsCompileTimeValue()) continue; 1401 if (property->IsCompileTimeValue()) continue;
1365 1402
1366 Literal* key = property->key(); 1403 Literal* key = property->key();
1367 Expression* value = property->value(); 1404 Expression* value = property->value();
1368 if (!result_saved) { 1405 if (!result_saved) {
1369 __ push(eax); // Save result on the stack 1406 __ push(eax); // Save result on the stack
1370 result_saved = true; 1407 result_saved = true;
1408 increment_stack_height();
1371 } 1409 }
1372 switch (property->kind()) { 1410 switch (property->kind()) {
1373 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1411 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1374 ASSERT(!CompileTimeValue::IsCompileTimeValue(value)); 1412 ASSERT(!CompileTimeValue::IsCompileTimeValue(value));
1375 // Fall through. 1413 // Fall through.
1376 case ObjectLiteral::Property::COMPUTED: 1414 case ObjectLiteral::Property::COMPUTED:
1377 if (key->handle()->IsSymbol()) { 1415 if (key->handle()->IsSymbol()) {
1378 if (property->emit_store()) { 1416 if (property->emit_store()) {
1379 VisitForAccumulatorValue(value); 1417 VisitForAccumulatorValue(value);
1380 __ mov(ecx, Immediate(key->handle())); 1418 __ mov(ecx, Immediate(key->handle()));
1381 __ mov(edx, Operand(esp, 0)); 1419 __ mov(edx, Operand(esp, 0));
1382 Handle<Code> ic = is_strict_mode() 1420 Handle<Code> ic = is_strict_mode()
1383 ? isolate()->builtins()->StoreIC_Initialize_Strict() 1421 ? isolate()->builtins()->StoreIC_Initialize_Strict()
1384 : isolate()->builtins()->StoreIC_Initialize(); 1422 : isolate()->builtins()->StoreIC_Initialize();
1385 __ call(ic, RelocInfo::CODE_TARGET, key->id()); 1423 __ call(ic, RelocInfo::CODE_TARGET, key->id());
1386 PrepareForBailoutForId(key->id(), NO_REGISTERS); 1424 PrepareForBailoutForId(key->id(), NO_REGISTERS);
1387 } else { 1425 } else {
1388 VisitForEffect(value); 1426 VisitForEffect(value);
1389 } 1427 }
1390 break; 1428 break;
1391 } 1429 }
1392 // Fall through. 1430 // Fall through.
1393 case ObjectLiteral::Property::PROTOTYPE: 1431 case ObjectLiteral::Property::PROTOTYPE:
1394 __ push(Operand(esp, 0)); // Duplicate receiver. 1432 __ push(Operand(esp, 0)); // Duplicate receiver.
1433 increment_stack_height();
1395 VisitForStackValue(key); 1434 VisitForStackValue(key);
1396 VisitForStackValue(value); 1435 VisitForStackValue(value);
1397 if (property->emit_store()) { 1436 if (property->emit_store()) {
1398 __ push(Immediate(Smi::FromInt(NONE))); // PropertyAttributes 1437 __ push(Immediate(Smi::FromInt(NONE))); // PropertyAttributes
1399 __ CallRuntime(Runtime::kSetProperty, 4); 1438 __ CallRuntime(Runtime::kSetProperty, 4);
1400 } else { 1439 } else {
1401 __ Drop(3); 1440 __ Drop(3);
1402 } 1441 }
1442 decrement_stack_height(3);
1403 break; 1443 break;
1404 case ObjectLiteral::Property::SETTER: 1444 case ObjectLiteral::Property::SETTER:
1405 case ObjectLiteral::Property::GETTER: 1445 case ObjectLiteral::Property::GETTER:
1406 __ push(Operand(esp, 0)); // Duplicate receiver. 1446 __ push(Operand(esp, 0)); // Duplicate receiver.
1447 increment_stack_height();
1407 VisitForStackValue(key); 1448 VisitForStackValue(key);
1408 __ push(Immediate(property->kind() == ObjectLiteral::Property::SETTER ? 1449 __ push(Immediate(property->kind() == ObjectLiteral::Property::SETTER ?
1409 Smi::FromInt(1) : 1450 Smi::FromInt(1) :
1410 Smi::FromInt(0))); 1451 Smi::FromInt(0)));
1452 increment_stack_height();
1411 VisitForStackValue(value); 1453 VisitForStackValue(value);
1412 __ CallRuntime(Runtime::kDefineAccessor, 4); 1454 __ CallRuntime(Runtime::kDefineAccessor, 4);
1455 decrement_stack_height(4);
1413 break; 1456 break;
1414 default: UNREACHABLE(); 1457 default: UNREACHABLE();
1415 } 1458 }
1416 } 1459 }
1417 1460
1418 if (expr->has_function()) { 1461 if (expr->has_function()) {
1419 ASSERT(result_saved); 1462 ASSERT(result_saved);
1420 __ push(Operand(esp, 0)); 1463 __ push(Operand(esp, 0));
1421 __ CallRuntime(Runtime::kToFastProperties, 1); 1464 __ CallRuntime(Runtime::kToFastProperties, 1);
1422 } 1465 }
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1465 // If the subexpression is a literal or a simple materialized literal it 1508 // If the subexpression is a literal or a simple materialized literal it
1466 // is already set in the cloned array. 1509 // is already set in the cloned array.
1467 if (subexpr->AsLiteral() != NULL || 1510 if (subexpr->AsLiteral() != NULL ||
1468 CompileTimeValue::IsCompileTimeValue(subexpr)) { 1511 CompileTimeValue::IsCompileTimeValue(subexpr)) {
1469 continue; 1512 continue;
1470 } 1513 }
1471 1514
1472 if (!result_saved) { 1515 if (!result_saved) {
1473 __ push(eax); 1516 __ push(eax);
1474 result_saved = true; 1517 result_saved = true;
1518 increment_stack_height();
1475 } 1519 }
1476 VisitForAccumulatorValue(subexpr); 1520 VisitForAccumulatorValue(subexpr);
1477 1521
1478 // Store the subexpression value in the array's elements. 1522 // Store the subexpression value in the array's elements.
1479 __ mov(ebx, Operand(esp, 0)); // Copy of array literal. 1523 __ mov(ebx, Operand(esp, 0)); // Copy of array literal.
1480 __ mov(ebx, FieldOperand(ebx, JSObject::kElementsOffset)); 1524 __ mov(ebx, FieldOperand(ebx, JSObject::kElementsOffset));
1481 int offset = FixedArray::kHeaderSize + (i * kPointerSize); 1525 int offset = FixedArray::kHeaderSize + (i * kPointerSize);
1482 __ mov(FieldOperand(ebx, offset), result_register()); 1526 __ mov(FieldOperand(ebx, offset), result_register());
1483 1527
1484 // Update the write barrier for the array store. 1528 // Update the write barrier for the array store.
1485 __ RecordWriteField(ebx, offset, result_register(), ecx, kDontSaveFPRegs); 1529 __ RecordWriteField(ebx, offset, result_register(), ecx, kDontSaveFPRegs);
1486 1530
1487 PrepareForBailoutForId(expr->GetIdForElement(i), NO_REGISTERS); 1531 PrepareForBailoutForId(expr->GetIdForElement(i), NO_REGISTERS);
1488 } 1532 }
1489 1533
1490 if (result_saved) { 1534 if (result_saved) {
1491 context()->PlugTOS(); 1535 context()->PlugTOS();
1492 } else { 1536 } else {
1493 context()->Plug(eax); 1537 context()->Plug(eax);
1494 } 1538 }
1495 } 1539 }
1496 1540
1497 1541
1498 void FullCodeGenerator::VisitAssignment(Assignment* expr) { 1542 void FullCodeGenerator::VisitAssignment(Assignment* expr) {
1499 Comment cmnt(masm_, "[ Assignment"); 1543 Comment cmnt(masm_, "[ Assignment");
1500 // Invalid left-hand sides are rewritten to have a 'throw ReferenceError' 1544 // Invalid left-hand sides are rewritten to have a 'throw ReferenceError'
1501 // on the left-hand side. 1545 // on the left-hand side.
1502 if (!expr->target()->IsValidLeftHandSide()) { 1546 if (!expr->target()->IsValidLeftHandSide()) {
1503 VisitForEffect(expr->target()); 1547 ASSERT(expr->target()->AsThrow() != NULL);
1548 VisitInCurrentContext(expr->target()); // Throw does not plug the context
1549 context()->Plug(eax);
1504 return; 1550 return;
1505 } 1551 }
1506 1552
1507 // Left-hand side can only be a property, a global or a (parameter or local) 1553 // Left-hand side can only be a property, a global or a (parameter or local)
1508 // slot. 1554 // slot.
1509 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; 1555 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
1510 LhsKind assign_type = VARIABLE; 1556 LhsKind assign_type = VARIABLE;
1511 Property* property = expr->target()->AsProperty(); 1557 Property* property = expr->target()->AsProperty();
1512 if (property != NULL) { 1558 if (property != NULL) {
1513 assign_type = (property->key()->IsPropertyName()) 1559 assign_type = (property->key()->IsPropertyName())
1514 ? NAMED_PROPERTY 1560 ? NAMED_PROPERTY
1515 : KEYED_PROPERTY; 1561 : KEYED_PROPERTY;
1516 } 1562 }
1517 1563
1518 // Evaluate LHS expression. 1564 // Evaluate LHS expression.
1519 switch (assign_type) { 1565 switch (assign_type) {
1520 case VARIABLE: 1566 case VARIABLE:
1521 // Nothing to do here. 1567 // Nothing to do here.
1522 break; 1568 break;
1523 case NAMED_PROPERTY: 1569 case NAMED_PROPERTY:
1524 if (expr->is_compound()) { 1570 if (expr->is_compound()) {
1525 // We need the receiver both on the stack and in the accumulator. 1571 // We need the receiver both on the stack and in the accumulator.
1526 VisitForAccumulatorValue(property->obj()); 1572 VisitForAccumulatorValue(property->obj());
1527 __ push(result_register()); 1573 __ push(result_register());
1574 increment_stack_height();
1528 } else { 1575 } else {
1529 VisitForStackValue(property->obj()); 1576 VisitForStackValue(property->obj());
1530 } 1577 }
1531 break; 1578 break;
1532 case KEYED_PROPERTY: { 1579 case KEYED_PROPERTY: {
1533 if (expr->is_compound()) { 1580 if (expr->is_compound()) {
1534 VisitForStackValue(property->obj()); 1581 VisitForStackValue(property->obj());
1535 VisitForAccumulatorValue(property->key()); 1582 VisitForAccumulatorValue(property->key());
1536 __ mov(edx, Operand(esp, 0)); 1583 __ mov(edx, Operand(esp, 0));
1537 __ push(eax); 1584 __ push(eax);
1585 increment_stack_height();
1538 } else { 1586 } else {
1539 VisitForStackValue(property->obj()); 1587 VisitForStackValue(property->obj());
1540 VisitForStackValue(property->key()); 1588 VisitForStackValue(property->key());
1541 } 1589 }
1542 break; 1590 break;
1543 } 1591 }
1544 } 1592 }
1545 1593
1546 // For compound assignments we need another deoptimization point after the 1594 // For compound assignments we need another deoptimization point after the
1547 // variable/property load. 1595 // variable/property load.
1548 if (expr->is_compound()) { 1596 if (expr->is_compound()) {
1549 { AccumulatorValueContext context(this); 1597 AccumulatorValueContext result_context(this);
1598 { AccumulatorValueContext left_operand_context(this);
1550 switch (assign_type) { 1599 switch (assign_type) {
1551 case VARIABLE: 1600 case VARIABLE:
1552 EmitVariableLoad(expr->target()->AsVariableProxy()->var()); 1601 EmitVariableLoad(expr->target()->AsVariableProxy());
1553 PrepareForBailout(expr->target(), TOS_REG); 1602 PrepareForBailout(expr->target(), TOS_REG);
1554 break; 1603 break;
1555 case NAMED_PROPERTY: 1604 case NAMED_PROPERTY:
1556 EmitNamedPropertyLoad(property); 1605 EmitNamedPropertyLoad(property);
1557 PrepareForBailoutForId(expr->CompoundLoadId(), TOS_REG); 1606 PrepareForBailoutForId(expr->CompoundLoadId(), TOS_REG);
1558 break; 1607 break;
1559 case KEYED_PROPERTY: 1608 case KEYED_PROPERTY:
1560 EmitKeyedPropertyLoad(property); 1609 EmitKeyedPropertyLoad(property);
1561 PrepareForBailoutForId(expr->CompoundLoadId(), TOS_REG); 1610 PrepareForBailoutForId(expr->CompoundLoadId(), TOS_REG);
1562 break; 1611 break;
1563 } 1612 }
1564 } 1613 }
1565 1614
1566 Token::Value op = expr->binary_op(); 1615 Token::Value op = expr->binary_op();
1567 __ push(eax); // Left operand goes on the stack. 1616 __ push(eax); // Left operand goes on the stack.
1617 increment_stack_height();
1568 VisitForAccumulatorValue(expr->value()); 1618 VisitForAccumulatorValue(expr->value());
1569 1619
1570 OverwriteMode mode = expr->value()->ResultOverwriteAllowed() 1620 OverwriteMode mode = expr->value()->ResultOverwriteAllowed()
1571 ? OVERWRITE_RIGHT 1621 ? OVERWRITE_RIGHT
1572 : NO_OVERWRITE; 1622 : NO_OVERWRITE;
1573 SetSourcePosition(expr->position() + 1); 1623 SetSourcePosition(expr->position() + 1);
1574 AccumulatorValueContext context(this);
1575 if (ShouldInlineSmiCase(op)) { 1624 if (ShouldInlineSmiCase(op)) {
1576 EmitInlineSmiBinaryOp(expr->binary_operation(), 1625 EmitInlineSmiBinaryOp(expr->binary_operation(),
1577 op, 1626 op,
1578 mode, 1627 mode,
1579 expr->target(), 1628 expr->target(),
1580 expr->value()); 1629 expr->value());
1581 } else { 1630 } else {
1582 EmitBinaryOp(expr->binary_operation(), op, mode); 1631 EmitBinaryOp(expr->binary_operation(), op, mode);
1583 } 1632 }
1584 1633
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1628 1677
1629 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, 1678 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
1630 Token::Value op, 1679 Token::Value op,
1631 OverwriteMode mode, 1680 OverwriteMode mode,
1632 Expression* left, 1681 Expression* left,
1633 Expression* right) { 1682 Expression* right) {
1634 // Do combined smi check of the operands. Left operand is on the 1683 // Do combined smi check of the operands. Left operand is on the
1635 // stack. Right operand is in eax. 1684 // stack. Right operand is in eax.
1636 Label smi_case, done, stub_call; 1685 Label smi_case, done, stub_call;
1637 __ pop(edx); 1686 __ pop(edx);
1687 decrement_stack_height();
1638 __ mov(ecx, eax); 1688 __ mov(ecx, eax);
1639 __ or_(eax, Operand(edx)); 1689 __ or_(eax, Operand(edx));
1640 JumpPatchSite patch_site(masm_); 1690 JumpPatchSite patch_site(masm_);
1641 patch_site.EmitJumpIfSmi(eax, &smi_case, Label::kNear); 1691 patch_site.EmitJumpIfSmi(eax, &smi_case, Label::kNear);
1642 1692
1643 __ bind(&stub_call); 1693 __ bind(&stub_call);
1644 __ mov(eax, ecx); 1694 __ mov(eax, ecx);
1645 BinaryOpStub stub(op, mode); 1695 BinaryOpStub stub(op, mode);
1646 __ call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id()); 1696 __ call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id());
1647 patch_site.EmitPatchInfo(); 1697 patch_site.EmitPatchInfo();
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
1719 1769
1720 __ bind(&done); 1770 __ bind(&done);
1721 context()->Plug(eax); 1771 context()->Plug(eax);
1722 } 1772 }
1723 1773
1724 1774
1725 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, 1775 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr,
1726 Token::Value op, 1776 Token::Value op,
1727 OverwriteMode mode) { 1777 OverwriteMode mode) {
1728 __ pop(edx); 1778 __ pop(edx);
1779 decrement_stack_height();
1729 BinaryOpStub stub(op, mode); 1780 BinaryOpStub stub(op, mode);
1730 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. 1781 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
1731 __ call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id()); 1782 __ call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id());
1732 patch_site.EmitPatchInfo(); 1783 patch_site.EmitPatchInfo();
1733 context()->Plug(eax); 1784 context()->Plug(eax);
1734 } 1785 }
1735 1786
1736 1787
1737 void FullCodeGenerator::EmitAssignment(Expression* expr, int bailout_ast_id) { 1788 void FullCodeGenerator::EmitAssignment(Expression* expr, int bailout_ast_id) {
1738 // Invalid left-hand sides are rewritten to have a 'throw 1789 // Invalid left-hand sides are rewritten to have a 'throw
1739 // ReferenceError' on the left-hand side. 1790 // ReferenceError' on the left-hand side.
1740 if (!expr->IsValidLeftHandSide()) { 1791 if (!expr->IsValidLeftHandSide()) {
1741 VisitForEffect(expr); 1792 ASSERT(expr->AsThrow() != NULL);
1793 VisitInCurrentContext(expr); // Throw does not plug the context
1794 context()->Plug(eax);
1742 return; 1795 return;
1743 } 1796 }
1744 1797
1745 // Left-hand side can only be a property, a global or a (parameter or local) 1798 // Left-hand side can only be a property, a global or a (parameter or local)
1746 // slot. 1799 // slot.
1747 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; 1800 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
1748 LhsKind assign_type = VARIABLE; 1801 LhsKind assign_type = VARIABLE;
1749 Property* prop = expr->AsProperty(); 1802 Property* prop = expr->AsProperty();
1750 if (prop != NULL) { 1803 if (prop != NULL) {
1751 assign_type = (prop->key()->IsPropertyName()) 1804 assign_type = (prop->key()->IsPropertyName())
1752 ? NAMED_PROPERTY 1805 ? NAMED_PROPERTY
1753 : KEYED_PROPERTY; 1806 : KEYED_PROPERTY;
1754 } 1807 }
1755 1808
1756 switch (assign_type) { 1809 switch (assign_type) {
1757 case VARIABLE: { 1810 case VARIABLE: {
1758 Variable* var = expr->AsVariableProxy()->var(); 1811 Variable* var = expr->AsVariableProxy()->var();
1759 EffectContext context(this); 1812 EffectContext context(this);
1760 EmitVariableAssignment(var, Token::ASSIGN); 1813 EmitVariableAssignment(var, Token::ASSIGN);
1761 break; 1814 break;
1762 } 1815 }
1763 case NAMED_PROPERTY: { 1816 case NAMED_PROPERTY: {
1764 __ push(eax); // Preserve value. 1817 __ push(eax); // Preserve value.
1818 increment_stack_height();
1765 VisitForAccumulatorValue(prop->obj()); 1819 VisitForAccumulatorValue(prop->obj());
1766 __ mov(edx, eax); 1820 __ mov(edx, eax);
1767 __ pop(eax); // Restore value. 1821 __ pop(eax); // Restore value.
1822 decrement_stack_height();
1768 __ mov(ecx, prop->key()->AsLiteral()->handle()); 1823 __ mov(ecx, prop->key()->AsLiteral()->handle());
1769 Handle<Code> ic = is_strict_mode() 1824 Handle<Code> ic = is_strict_mode()
1770 ? isolate()->builtins()->StoreIC_Initialize_Strict() 1825 ? isolate()->builtins()->StoreIC_Initialize_Strict()
1771 : isolate()->builtins()->StoreIC_Initialize(); 1826 : isolate()->builtins()->StoreIC_Initialize();
1772 __ call(ic); 1827 __ call(ic);
1773 break; 1828 break;
1774 } 1829 }
1775 case KEYED_PROPERTY: { 1830 case KEYED_PROPERTY: {
1776 __ push(eax); // Preserve value. 1831 __ push(eax); // Preserve value.
1832 increment_stack_height();
1777 if (prop->is_synthetic()) { 1833 if (prop->is_synthetic()) {
1778 ASSERT(prop->obj()->AsVariableProxy() != NULL); 1834 ASSERT(prop->obj()->AsVariableProxy() != NULL);
1779 ASSERT(prop->key()->AsLiteral() != NULL); 1835 ASSERT(prop->key()->AsLiteral() != NULL);
1780 { AccumulatorValueContext for_object(this); 1836 { AccumulatorValueContext for_object(this);
1781 EmitVariableLoad(prop->obj()->AsVariableProxy()->var()); 1837 EmitVariableLoad(prop->obj()->AsVariableProxy());
1782 } 1838 }
1783 __ mov(edx, eax); 1839 __ mov(edx, eax);
1784 __ SafeSet(ecx, Immediate(prop->key()->AsLiteral()->handle())); 1840 __ SafeSet(ecx, Immediate(prop->key()->AsLiteral()->handle()));
1785 } else { 1841 } else {
1786 VisitForStackValue(prop->obj()); 1842 VisitForStackValue(prop->obj());
1787 VisitForAccumulatorValue(prop->key()); 1843 VisitForAccumulatorValue(prop->key());
1788 __ mov(ecx, eax); 1844 __ mov(ecx, eax);
1789 __ pop(edx); 1845 __ pop(edx);
1846 decrement_stack_height();
1790 } 1847 }
1791 __ pop(eax); // Restore value. 1848 __ pop(eax); // Restore value.
1849 decrement_stack_height();
1792 Handle<Code> ic = is_strict_mode() 1850 Handle<Code> ic = is_strict_mode()
1793 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 1851 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
1794 : isolate()->builtins()->KeyedStoreIC_Initialize(); 1852 : isolate()->builtins()->KeyedStoreIC_Initialize();
1795 __ call(ic); 1853 __ call(ic);
1796 break; 1854 break;
1797 } 1855 }
1798 } 1856 }
1799 PrepareForBailoutForId(bailout_ast_id, TOS_REG); 1857 PrepareForBailoutForId(bailout_ast_id, TOS_REG);
1800 context()->Plug(eax); 1858 context()->Plug(eax);
1801 } 1859 }
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
1899 __ pop(result_register()); 1957 __ pop(result_register());
1900 } 1958 }
1901 1959
1902 // Record source code position before IC call. 1960 // Record source code position before IC call.
1903 SetSourcePosition(expr->position()); 1961 SetSourcePosition(expr->position());
1904 __ mov(ecx, prop->key()->AsLiteral()->handle()); 1962 __ mov(ecx, prop->key()->AsLiteral()->handle());
1905 if (expr->ends_initialization_block()) { 1963 if (expr->ends_initialization_block()) {
1906 __ mov(edx, Operand(esp, 0)); 1964 __ mov(edx, Operand(esp, 0));
1907 } else { 1965 } else {
1908 __ pop(edx); 1966 __ pop(edx);
1967 decrement_stack_height();
1909 } 1968 }
1910 Handle<Code> ic = is_strict_mode() 1969 Handle<Code> ic = is_strict_mode()
1911 ? isolate()->builtins()->StoreIC_Initialize_Strict() 1970 ? isolate()->builtins()->StoreIC_Initialize_Strict()
1912 : isolate()->builtins()->StoreIC_Initialize(); 1971 : isolate()->builtins()->StoreIC_Initialize();
1913 __ call(ic, RelocInfo::CODE_TARGET, expr->id()); 1972 __ call(ic, RelocInfo::CODE_TARGET, expr->id());
1914 1973
1915 // If the assignment ends an initialization block, revert to fast case. 1974 // If the assignment ends an initialization block, revert to fast case.
1916 if (expr->ends_initialization_block()) { 1975 if (expr->ends_initialization_block()) {
1917 __ push(eax); // Result of assignment, saved even if not needed. 1976 __ push(eax); // Result of assignment, saved even if not needed.
1918 __ push(Operand(esp, kPointerSize)); // Receiver is under value. 1977 __ push(Operand(esp, kPointerSize)); // Receiver is under value.
1919 __ CallRuntime(Runtime::kToFastProperties, 1); 1978 __ CallRuntime(Runtime::kToFastProperties, 1);
1920 __ pop(eax); 1979 __ pop(eax);
1921 __ Drop(1); 1980 __ Drop(1);
1981 decrement_stack_height();
1922 } 1982 }
1923 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 1983 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
1924 context()->Plug(eax); 1984 context()->Plug(eax);
1925 } 1985 }
1926 1986
1927 1987
1928 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { 1988 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
1929 // Assignment to a property, using a keyed store IC. 1989 // Assignment to a property, using a keyed store IC.
1930 1990
1931 // If the assignment starts a block of assignments to the same object, 1991 // If the assignment starts a block of assignments to the same object,
1932 // change to slow case to avoid the quadratic behavior of repeatedly 1992 // change to slow case to avoid the quadratic behavior of repeatedly
1933 // adding fast properties. 1993 // adding fast properties.
1934 if (expr->starts_initialization_block()) { 1994 if (expr->starts_initialization_block()) {
1935 __ push(result_register()); 1995 __ push(result_register());
1936 // Receiver is now under the key and value. 1996 // Receiver is now under the key and value.
1937 __ push(Operand(esp, 2 * kPointerSize)); 1997 __ push(Operand(esp, 2 * kPointerSize));
1938 __ CallRuntime(Runtime::kToSlowProperties, 1); 1998 __ CallRuntime(Runtime::kToSlowProperties, 1);
1939 __ pop(result_register()); 1999 __ pop(result_register());
1940 } 2000 }
1941 2001
1942 __ pop(ecx); 2002 __ pop(ecx);
2003 decrement_stack_height();
1943 if (expr->ends_initialization_block()) { 2004 if (expr->ends_initialization_block()) {
1944 __ mov(edx, Operand(esp, 0)); // Leave receiver on the stack for later. 2005 __ mov(edx, Operand(esp, 0)); // Leave receiver on the stack for later.
1945 } else { 2006 } else {
1946 __ pop(edx); 2007 __ pop(edx);
2008 decrement_stack_height();
1947 } 2009 }
1948 // Record source code position before IC call. 2010 // Record source code position before IC call.
1949 SetSourcePosition(expr->position()); 2011 SetSourcePosition(expr->position());
1950 Handle<Code> ic = is_strict_mode() 2012 Handle<Code> ic = is_strict_mode()
1951 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 2013 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
1952 : isolate()->builtins()->KeyedStoreIC_Initialize(); 2014 : isolate()->builtins()->KeyedStoreIC_Initialize();
1953 __ call(ic, RelocInfo::CODE_TARGET, expr->id()); 2015 __ call(ic, RelocInfo::CODE_TARGET, expr->id());
1954 2016
1955 // If the assignment ends an initialization block, revert to fast case. 2017 // If the assignment ends an initialization block, revert to fast case.
1956 if (expr->ends_initialization_block()) { 2018 if (expr->ends_initialization_block()) {
1957 __ pop(edx); 2019 __ pop(edx);
1958 __ push(eax); // Result of assignment, saved even if not needed. 2020 __ push(eax); // Result of assignment, saved even if not needed.
1959 __ push(edx); 2021 __ push(edx);
1960 __ CallRuntime(Runtime::kToFastProperties, 1); 2022 __ CallRuntime(Runtime::kToFastProperties, 1);
1961 __ pop(eax); 2023 __ pop(eax);
2024 decrement_stack_height();
1962 } 2025 }
1963 2026
1964 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2027 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
1965 context()->Plug(eax); 2028 context()->Plug(eax);
1966 } 2029 }
1967 2030
1968 2031
1969 void FullCodeGenerator::VisitProperty(Property* expr) { 2032 void FullCodeGenerator::VisitProperty(Property* expr) {
1970 Comment cmnt(masm_, "[ Property"); 2033 Comment cmnt(masm_, "[ Property");
1971 Expression* key = expr->key(); 2034 Expression* key = expr->key();
1972 2035
1973 if (key->IsPropertyName()) { 2036 if (key->IsPropertyName()) {
1974 VisitForAccumulatorValue(expr->obj()); 2037 VisitForAccumulatorValue(expr->obj());
1975 EmitNamedPropertyLoad(expr); 2038 EmitNamedPropertyLoad(expr);
1976 context()->Plug(eax); 2039 context()->Plug(eax);
1977 } else { 2040 } else {
1978 VisitForStackValue(expr->obj()); 2041 VisitForStackValue(expr->obj());
1979 VisitForAccumulatorValue(expr->key()); 2042 VisitForAccumulatorValue(expr->key());
1980 __ pop(edx); 2043 __ pop(edx);
2044 decrement_stack_height();
1981 EmitKeyedPropertyLoad(expr); 2045 EmitKeyedPropertyLoad(expr);
1982 context()->Plug(eax); 2046 context()->Plug(eax);
1983 } 2047 }
1984 } 2048 }
1985 2049
1986 2050
1987 void FullCodeGenerator::EmitCallWithIC(Call* expr, 2051 void FullCodeGenerator::EmitCallWithIC(Call* expr,
1988 Handle<Object> name, 2052 Handle<Object> name,
1989 RelocInfo::Mode mode) { 2053 RelocInfo::Mode mode) {
1990 // Code common for calls using the IC. 2054 // Code common for calls using the IC.
1991 ZoneList<Expression*>* args = expr->arguments(); 2055 ZoneList<Expression*>* args = expr->arguments();
1992 int arg_count = args->length(); 2056 int arg_count = args->length();
1993 { PreservePositionScope scope(masm()->positions_recorder()); 2057 { PreservePositionScope scope(masm()->positions_recorder());
1994 for (int i = 0; i < arg_count; i++) { 2058 for (int i = 0; i < arg_count; i++) {
1995 VisitForStackValue(args->at(i)); 2059 VisitForStackValue(args->at(i));
1996 } 2060 }
1997 __ Set(ecx, Immediate(name)); 2061 __ Set(ecx, Immediate(name));
1998 } 2062 }
1999 // Record source position of the IC call. 2063 // Record source position of the IC call.
2000 SetSourcePosition(expr->position()); 2064 SetSourcePosition(expr->position());
2001 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; 2065 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
2002 Handle<Code> ic = 2066 Handle<Code> ic =
2003 isolate()->stub_cache()->ComputeCallInitialize(arg_count, in_loop, mode); 2067 isolate()->stub_cache()->ComputeCallInitialize(arg_count, in_loop, mode);
2004 __ call(ic, mode, expr->id()); 2068 __ call(ic, mode, expr->id());
2005 RecordJSReturnSite(expr); 2069 RecordJSReturnSite(expr);
2006 // Restore context register. 2070 // Restore context register.
2007 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2071 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2072 decrement_stack_height(arg_count + 1);
2008 context()->Plug(eax); 2073 context()->Plug(eax);
2009 } 2074 }
2010 2075
2011 2076
2012 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, 2077 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr,
2013 Expression* key) { 2078 Expression* key) {
2014 // Load the key. 2079 // Load the key.
2015 VisitForAccumulatorValue(key); 2080 VisitForAccumulatorValue(key);
2016 2081
2017 // Swap the name of the function and the receiver on the stack to follow 2082 // Swap the name of the function and the receiver on the stack to follow
2018 // the calling convention for call ICs. 2083 // the calling convention for call ICs.
2019 __ pop(ecx); 2084 __ pop(ecx);
2020 __ push(eax); 2085 __ push(eax);
2021 __ push(ecx); 2086 __ push(ecx);
2087 increment_stack_height();
2022 2088
2023 // Load the arguments. 2089 // Load the arguments.
2024 ZoneList<Expression*>* args = expr->arguments(); 2090 ZoneList<Expression*>* args = expr->arguments();
2025 int arg_count = args->length(); 2091 int arg_count = args->length();
2026 { PreservePositionScope scope(masm()->positions_recorder()); 2092 { PreservePositionScope scope(masm()->positions_recorder());
2027 for (int i = 0; i < arg_count; i++) { 2093 for (int i = 0; i < arg_count; i++) {
2028 VisitForStackValue(args->at(i)); 2094 VisitForStackValue(args->at(i));
2029 } 2095 }
2030 } 2096 }
2031 // Record source position of the IC call. 2097 // Record source position of the IC call.
2032 SetSourcePosition(expr->position()); 2098 SetSourcePosition(expr->position());
2033 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; 2099 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
2034 Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedCallInitialize( 2100 Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedCallInitialize(
2035 arg_count, in_loop); 2101 arg_count, in_loop);
2036 __ mov(ecx, Operand(esp, (arg_count + 1) * kPointerSize)); // Key. 2102 __ mov(ecx, Operand(esp, (arg_count + 1) * kPointerSize)); // Key.
2037 __ call(ic, RelocInfo::CODE_TARGET, expr->id()); 2103 __ call(ic, RelocInfo::CODE_TARGET, expr->id());
2038 RecordJSReturnSite(expr); 2104 RecordJSReturnSite(expr);
2039 // Restore context register. 2105 // Restore context register.
2040 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2106 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2107 decrement_stack_height(arg_count + 1);
2041 context()->DropAndPlug(1, eax); // Drop the key still on the stack. 2108 context()->DropAndPlug(1, eax); // Drop the key still on the stack.
2042 } 2109 }
2043 2110
2044 2111
2045 void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) { 2112 void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) {
2046 // Code common for calls using the call stub. 2113 // Code common for calls using the call stub.
2047 ZoneList<Expression*>* args = expr->arguments(); 2114 ZoneList<Expression*>* args = expr->arguments();
2048 int arg_count = args->length(); 2115 int arg_count = args->length();
2049 { PreservePositionScope scope(masm()->positions_recorder()); 2116 { PreservePositionScope scope(masm()->positions_recorder());
2050 for (int i = 0; i < arg_count; i++) { 2117 for (int i = 0; i < arg_count; i++) {
2051 VisitForStackValue(args->at(i)); 2118 VisitForStackValue(args->at(i));
2052 } 2119 }
2053 } 2120 }
2054 // Record source position for debugger. 2121 // Record source position for debugger.
2055 SetSourcePosition(expr->position()); 2122 SetSourcePosition(expr->position());
2056 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; 2123 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
2057 CallFunctionStub stub(arg_count, in_loop, flags); 2124 CallFunctionStub stub(arg_count, in_loop, flags);
2058 __ CallStub(&stub); 2125 __ CallStub(&stub);
2059 RecordJSReturnSite(expr); 2126 RecordJSReturnSite(expr);
2060 // Restore context register. 2127 // Restore context register.
2061 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2128 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2129
2130 decrement_stack_height(arg_count + 1);
2062 context()->DropAndPlug(1, eax); 2131 context()->DropAndPlug(1, eax);
2063 } 2132 }
2064 2133
2065 2134
2066 void FullCodeGenerator::EmitResolvePossiblyDirectEval(ResolveEvalFlag flag, 2135 void FullCodeGenerator::EmitResolvePossiblyDirectEval(ResolveEvalFlag flag,
2067 int arg_count) { 2136 int arg_count) {
2068 // Push copy of the first argument or undefined if it doesn't exist. 2137 // Push copy of the first argument or undefined if it doesn't exist.
2069 if (arg_count > 0) { 2138 if (arg_count > 0) {
2070 __ push(Operand(esp, arg_count * kPointerSize)); 2139 __ push(Operand(esp, arg_count * kPointerSize));
2071 } else { 2140 } else {
(...skipping 27 matching lines...) Expand all
2099 // In a call to eval, we first call %ResolvePossiblyDirectEval to 2168 // In a call to eval, we first call %ResolvePossiblyDirectEval to
2100 // resolve the function we need to call and the receiver of the 2169 // resolve the function we need to call and the receiver of the
2101 // call. Then we call the resolved function using the given 2170 // call. Then we call the resolved function using the given
2102 // arguments. 2171 // arguments.
2103 ZoneList<Expression*>* args = expr->arguments(); 2172 ZoneList<Expression*>* args = expr->arguments();
2104 int arg_count = args->length(); 2173 int arg_count = args->length();
2105 { PreservePositionScope pos_scope(masm()->positions_recorder()); 2174 { PreservePositionScope pos_scope(masm()->positions_recorder());
2106 VisitForStackValue(fun); 2175 VisitForStackValue(fun);
2107 // Reserved receiver slot. 2176 // Reserved receiver slot.
2108 __ push(Immediate(isolate()->factory()->undefined_value())); 2177 __ push(Immediate(isolate()->factory()->undefined_value()));
2109 2178 increment_stack_height();
2110 // Push the arguments. 2179 // Push the arguments.
2111 for (int i = 0; i < arg_count; i++) { 2180 for (int i = 0; i < arg_count; i++) {
2112 VisitForStackValue(args->at(i)); 2181 VisitForStackValue(args->at(i));
2113 } 2182 }
2114 2183
2115 // If we know that eval can only be shadowed by eval-introduced 2184 // If we know that eval can only be shadowed by eval-introduced
2116 // variables we attempt to load the global eval function directly 2185 // variables we attempt to load the global eval function directly
2117 // in generated code. If we succeed, there is no need to perform a 2186 // in generated code. If we succeed, there is no need to perform a
2118 // context lookup in the runtime system. 2187 // context lookup in the runtime system.
2119 Label done; 2188 Label done;
(...skipping 23 matching lines...) Expand all
2143 __ mov(Operand(esp, (arg_count + 1) * kPointerSize), eax); 2212 __ mov(Operand(esp, (arg_count + 1) * kPointerSize), eax);
2144 } 2213 }
2145 // Record source position for debugger. 2214 // Record source position for debugger.
2146 SetSourcePosition(expr->position()); 2215 SetSourcePosition(expr->position());
2147 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; 2216 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
2148 CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_IMPLICIT); 2217 CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_IMPLICIT);
2149 __ CallStub(&stub); 2218 __ CallStub(&stub);
2150 RecordJSReturnSite(expr); 2219 RecordJSReturnSite(expr);
2151 // Restore context register. 2220 // Restore context register.
2152 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2221 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2222 decrement_stack_height(arg_count + 1); // Function is left on the stack.
2153 context()->DropAndPlug(1, eax); 2223 context()->DropAndPlug(1, eax);
2154 } else if (var != NULL && !var->is_this() && var->is_global()) { 2224 } else if (var != NULL && !var->is_this() && var->is_global()) {
2155 // Push global object as receiver for the call IC. 2225 // Push global object as receiver for the call IC.
2156 __ push(GlobalObjectOperand()); 2226 __ push(GlobalObjectOperand());
2227 increment_stack_height();
2157 EmitCallWithIC(expr, var->name(), RelocInfo::CODE_TARGET_CONTEXT); 2228 EmitCallWithIC(expr, var->name(), RelocInfo::CODE_TARGET_CONTEXT);
2158 } else if (var != NULL && var->AsSlot() != NULL && 2229 } else if (var != NULL && var->AsSlot() != NULL &&
2159 var->AsSlot()->type() == Slot::LOOKUP) { 2230 var->AsSlot()->type() == Slot::LOOKUP) {
2160 // Call to a lookup slot (dynamically introduced variable). 2231 // Call to a lookup slot (dynamically introduced variable).
2161 Label slow, done; 2232 Label slow, done;
2162 2233
2163 { PreservePositionScope scope(masm()->positions_recorder()); 2234 { PreservePositionScope scope(masm()->positions_recorder());
2164 // Generate code for loading from variables potentially shadowed 2235 // Generate code for loading from variables potentially shadowed
2165 // by eval-introduced variables. 2236 // by eval-introduced variables.
2166 EmitDynamicLoadFromSlotFastCase(var->AsSlot(), 2237 EmitDynamicLoadFromSlotFastCase(var->AsSlot(),
2167 NOT_INSIDE_TYPEOF, 2238 NOT_INSIDE_TYPEOF,
2168 &slow, 2239 &slow,
2169 &done); 2240 &done);
2170 } 2241 }
2171 2242
2172 __ bind(&slow); 2243 __ bind(&slow);
2173 // Call the runtime to find the function to call (returned in eax) 2244 // Call the runtime to find the function to call (returned in eax)
2174 // and the object holding it (returned in edx). 2245 // and the object holding it (returned in edx).
2175 __ push(context_register()); 2246 __ push(context_register());
2176 __ push(Immediate(var->name())); 2247 __ push(Immediate(var->name()));
2177 __ CallRuntime(Runtime::kLoadContextSlot, 2); 2248 __ CallRuntime(Runtime::kLoadContextSlot, 2);
2178 __ push(eax); // Function. 2249 __ push(eax); // Function.
2250 increment_stack_height();
2179 __ push(edx); // Receiver. 2251 __ push(edx); // Receiver.
2252 increment_stack_height();
2180 2253
2181 // If fast case code has been generated, emit code to push the 2254 // If fast case code has been generated, emit code to push the
2182 // function and receiver and have the slow path jump around this 2255 // function and receiver and have the slow path jump around this
2183 // code. 2256 // code.
2184 if (done.is_linked()) { 2257 if (done.is_linked()) {
2185 Label call; 2258 Label call;
2186 __ jmp(&call); 2259 __ jmp(&call);
2187 __ bind(&done); 2260 __ bind(&done);
2188 // Push function. 2261 // Push function. Stack height already incremented in slow case above.
2189 __ push(eax); 2262 __ push(eax);
2190 // The receiver is implicitly the global receiver. Indicate this 2263 // The receiver is implicitly the global receiver. Indicate this
2191 // by passing the hole to the call function stub. 2264 // by passing the hole to the call function stub.
2192 __ push(Immediate(isolate()->factory()->the_hole_value())); 2265 __ push(Immediate(isolate()->factory()->the_hole_value()));
2193 __ bind(&call); 2266 __ bind(&call);
2194 } 2267 }
2195 2268
2196 // The receiver is either the global receiver or an object found 2269 // The receiver is either the global receiver or an object found
2197 // by LoadContextSlot. That object could be the hole if the 2270 // by LoadContextSlot. That object could be the hole if the
2198 // receiver is implicitly the global object. 2271 // receiver is implicitly the global object.
(...skipping 25 matching lines...) Expand all
2224 ASSERT(prop->key()->AsLiteral()->handle()->IsSmi()); 2297 ASSERT(prop->key()->AsLiteral()->handle()->IsSmi());
2225 __ mov(eax, prop->key()->AsLiteral()->handle()); 2298 __ mov(eax, prop->key()->AsLiteral()->handle());
2226 2299
2227 // Record source code position for IC call. 2300 // Record source code position for IC call.
2228 SetSourcePosition(prop->position()); 2301 SetSourcePosition(prop->position());
2229 2302
2230 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); 2303 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
2231 __ call(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop)); 2304 __ call(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop));
2232 // Push result (function). 2305 // Push result (function).
2233 __ push(eax); 2306 __ push(eax);
2307 increment_stack_height();
2234 // Push Global receiver. 2308 // Push Global receiver.
2235 __ mov(ecx, GlobalObjectOperand()); 2309 __ mov(ecx, GlobalObjectOperand());
2236 __ push(FieldOperand(ecx, GlobalObject::kGlobalReceiverOffset)); 2310 __ push(FieldOperand(ecx, GlobalObject::kGlobalReceiverOffset));
2311 increment_stack_height();
2237 EmitCallWithStub(expr, NO_CALL_FUNCTION_FLAGS); 2312 EmitCallWithStub(expr, NO_CALL_FUNCTION_FLAGS);
2238 } else { 2313 } else {
2239 { PreservePositionScope scope(masm()->positions_recorder()); 2314 { PreservePositionScope scope(masm()->positions_recorder());
2240 VisitForStackValue(prop->obj()); 2315 VisitForStackValue(prop->obj());
2241 } 2316 }
2242 EmitKeyedCallWithIC(expr, prop->key()); 2317 EmitKeyedCallWithIC(expr, prop->key());
2243 } 2318 }
2244 } 2319 }
2245 } else { 2320 } else {
2246 { PreservePositionScope scope(masm()->positions_recorder()); 2321 { PreservePositionScope scope(masm()->positions_recorder());
2247 VisitForStackValue(fun); 2322 VisitForStackValue(fun);
2248 } 2323 }
2249 // Load global receiver object. 2324 // Load global receiver object.
2250 __ mov(ebx, GlobalObjectOperand()); 2325 __ mov(ebx, GlobalObjectOperand());
2251 __ push(FieldOperand(ebx, GlobalObject::kGlobalReceiverOffset)); 2326 __ push(FieldOperand(ebx, GlobalObject::kGlobalReceiverOffset));
2327 increment_stack_height();
2252 // Emit function call. 2328 // Emit function call.
2253 EmitCallWithStub(expr, NO_CALL_FUNCTION_FLAGS); 2329 EmitCallWithStub(expr, NO_CALL_FUNCTION_FLAGS);
2254 } 2330 }
2255 2331
2256 #ifdef DEBUG 2332 #ifdef DEBUG
2257 // RecordJSReturnSite should have been called. 2333 // RecordJSReturnSite should have been called.
2258 ASSERT(expr->return_is_recorded_); 2334 ASSERT(expr->return_is_recorded_);
2259 #endif 2335 #endif
2260 } 2336 }
2261 2337
(...skipping 20 matching lines...) Expand all
2282 // constructor invocation. 2358 // constructor invocation.
2283 SetSourcePosition(expr->position()); 2359 SetSourcePosition(expr->position());
2284 2360
2285 // Load function and argument count into edi and eax. 2361 // Load function and argument count into edi and eax.
2286 __ SafeSet(eax, Immediate(arg_count)); 2362 __ SafeSet(eax, Immediate(arg_count));
2287 __ mov(edi, Operand(esp, arg_count * kPointerSize)); 2363 __ mov(edi, Operand(esp, arg_count * kPointerSize));
2288 2364
2289 Handle<Code> construct_builtin = 2365 Handle<Code> construct_builtin =
2290 isolate()->builtins()->JSConstructCall(); 2366 isolate()->builtins()->JSConstructCall();
2291 __ call(construct_builtin, RelocInfo::CONSTRUCT_CALL); 2367 __ call(construct_builtin, RelocInfo::CONSTRUCT_CALL);
2368
2369 decrement_stack_height(arg_count + 1);
2292 context()->Plug(eax); 2370 context()->Plug(eax);
2293 } 2371 }
2294 2372
2295 2373
2296 void FullCodeGenerator::EmitIsSmi(ZoneList<Expression*>* args) { 2374 void FullCodeGenerator::EmitIsSmi(ZoneList<Expression*>* args) {
2297 ASSERT(args->length() == 1); 2375 ASSERT(args->length() == 1);
2298 2376
2299 VisitForAccumulatorValue(args->at(0)); 2377 VisitForAccumulatorValue(args->at(0));
2300 2378
2301 Label materialize_true, materialize_false; 2379 Label materialize_true, materialize_false;
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after
2594 VisitForAccumulatorValue(args->at(1)); 2672 VisitForAccumulatorValue(args->at(1));
2595 2673
2596 Label materialize_true, materialize_false; 2674 Label materialize_true, materialize_false;
2597 Label* if_true = NULL; 2675 Label* if_true = NULL;
2598 Label* if_false = NULL; 2676 Label* if_false = NULL;
2599 Label* fall_through = NULL; 2677 Label* fall_through = NULL;
2600 context()->PrepareTest(&materialize_true, &materialize_false, 2678 context()->PrepareTest(&materialize_true, &materialize_false,
2601 &if_true, &if_false, &fall_through); 2679 &if_true, &if_false, &fall_through);
2602 2680
2603 __ pop(ebx); 2681 __ pop(ebx);
2682 decrement_stack_height();
2604 __ cmp(eax, Operand(ebx)); 2683 __ cmp(eax, Operand(ebx));
2605 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); 2684 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
2606 Split(equal, if_true, if_false, fall_through); 2685 Split(equal, if_true, if_false, fall_through);
2607 2686
2608 context()->Plug(if_true, if_false); 2687 context()->Plug(if_true, if_false);
2609 } 2688 }
2610 2689
2611 2690
2612 void FullCodeGenerator::EmitArguments(ZoneList<Expression*>* args) { 2691 void FullCodeGenerator::EmitArguments(ZoneList<Expression*>* args) {
2613 ASSERT(args->length() == 1); 2692 ASSERT(args->length() == 1);
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
2704 2783
2705 void FullCodeGenerator::EmitLog(ZoneList<Expression*>* args) { 2784 void FullCodeGenerator::EmitLog(ZoneList<Expression*>* args) {
2706 // Conditionally generate a log call. 2785 // Conditionally generate a log call.
2707 // Args: 2786 // Args:
2708 // 0 (literal string): The type of logging (corresponds to the flags). 2787 // 0 (literal string): The type of logging (corresponds to the flags).
2709 // This is used to determine whether or not to generate the log call. 2788 // This is used to determine whether or not to generate the log call.
2710 // 1 (string): Format string. Access the string at argument index 2 2789 // 1 (string): Format string. Access the string at argument index 2
2711 // with '%2s' (see Logger::LogRuntime for all the formats). 2790 // with '%2s' (see Logger::LogRuntime for all the formats).
2712 // 2 (array): Arguments to the format string. 2791 // 2 (array): Arguments to the format string.
2713 ASSERT_EQ(args->length(), 3); 2792 ASSERT_EQ(args->length(), 3);
2714 #ifdef ENABLE_LOGGING_AND_PROFILING
2715 if (CodeGenerator::ShouldGenerateLog(args->at(0))) { 2793 if (CodeGenerator::ShouldGenerateLog(args->at(0))) {
2716 VisitForStackValue(args->at(1)); 2794 VisitForStackValue(args->at(1));
2717 VisitForStackValue(args->at(2)); 2795 VisitForStackValue(args->at(2));
2718 __ CallRuntime(Runtime::kLog, 2); 2796 __ CallRuntime(Runtime::kLog, 2);
2797 decrement_stack_height(2);
2719 } 2798 }
2720 #endif
2721 // Finally, we're expected to leave a value on the top of the stack. 2799 // Finally, we're expected to leave a value on the top of the stack.
2722 __ mov(eax, isolate()->factory()->undefined_value()); 2800 __ mov(eax, isolate()->factory()->undefined_value());
2723 context()->Plug(eax); 2801 context()->Plug(eax);
2724 } 2802 }
2725 2803
2726 2804
2727 void FullCodeGenerator::EmitRandomHeapNumber(ZoneList<Expression*>* args) { 2805 void FullCodeGenerator::EmitRandomHeapNumber(ZoneList<Expression*>* args) {
2728 ASSERT(args->length() == 0); 2806 ASSERT(args->length() == 0);
2729 2807
2730 Label slow_allocate_heapnumber; 2808 Label slow_allocate_heapnumber;
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
2775 2853
2776 2854
2777 void FullCodeGenerator::EmitSubString(ZoneList<Expression*>* args) { 2855 void FullCodeGenerator::EmitSubString(ZoneList<Expression*>* args) {
2778 // Load the arguments on the stack and call the stub. 2856 // Load the arguments on the stack and call the stub.
2779 SubStringStub stub; 2857 SubStringStub stub;
2780 ASSERT(args->length() == 3); 2858 ASSERT(args->length() == 3);
2781 VisitForStackValue(args->at(0)); 2859 VisitForStackValue(args->at(0));
2782 VisitForStackValue(args->at(1)); 2860 VisitForStackValue(args->at(1));
2783 VisitForStackValue(args->at(2)); 2861 VisitForStackValue(args->at(2));
2784 __ CallStub(&stub); 2862 __ CallStub(&stub);
2863 decrement_stack_height(3);
2785 context()->Plug(eax); 2864 context()->Plug(eax);
2786 } 2865 }
2787 2866
2788 2867
2789 void FullCodeGenerator::EmitRegExpExec(ZoneList<Expression*>* args) { 2868 void FullCodeGenerator::EmitRegExpExec(ZoneList<Expression*>* args) {
2790 // Load the arguments on the stack and call the stub. 2869 // Load the arguments on the stack and call the stub.
2791 RegExpExecStub stub; 2870 RegExpExecStub stub;
2792 ASSERT(args->length() == 4); 2871 ASSERT(args->length() == 4);
2793 VisitForStackValue(args->at(0)); 2872 VisitForStackValue(args->at(0));
2794 VisitForStackValue(args->at(1)); 2873 VisitForStackValue(args->at(1));
2795 VisitForStackValue(args->at(2)); 2874 VisitForStackValue(args->at(2));
2796 VisitForStackValue(args->at(3)); 2875 VisitForStackValue(args->at(3));
2797 __ CallStub(&stub); 2876 __ CallStub(&stub);
2877 decrement_stack_height(4);
2798 context()->Plug(eax); 2878 context()->Plug(eax);
2799 } 2879 }
2800 2880
2801 2881
2802 void FullCodeGenerator::EmitValueOf(ZoneList<Expression*>* args) { 2882 void FullCodeGenerator::EmitValueOf(ZoneList<Expression*>* args) {
2803 ASSERT(args->length() == 1); 2883 ASSERT(args->length() == 1);
2804 2884
2805 VisitForAccumulatorValue(args->at(0)); // Load the object. 2885 VisitForAccumulatorValue(args->at(0)); // Load the object.
2806 2886
2807 Label done; 2887 Label done;
(...skipping 14 matching lines...) Expand all
2822 ASSERT(args->length() == 2); 2902 ASSERT(args->length() == 2);
2823 VisitForStackValue(args->at(0)); 2903 VisitForStackValue(args->at(0));
2824 VisitForStackValue(args->at(1)); 2904 VisitForStackValue(args->at(1));
2825 2905
2826 if (CpuFeatures::IsSupported(SSE2)) { 2906 if (CpuFeatures::IsSupported(SSE2)) {
2827 MathPowStub stub; 2907 MathPowStub stub;
2828 __ CallStub(&stub); 2908 __ CallStub(&stub);
2829 } else { 2909 } else {
2830 __ CallRuntime(Runtime::kMath_pow, 2); 2910 __ CallRuntime(Runtime::kMath_pow, 2);
2831 } 2911 }
2912 decrement_stack_height(2);
2832 context()->Plug(eax); 2913 context()->Plug(eax);
2833 } 2914 }
2834 2915
2835 2916
2836 void FullCodeGenerator::EmitSetValueOf(ZoneList<Expression*>* args) { 2917 void FullCodeGenerator::EmitSetValueOf(ZoneList<Expression*>* args) {
2837 ASSERT(args->length() == 2); 2918 ASSERT(args->length() == 2);
2838 2919
2839 VisitForStackValue(args->at(0)); // Load the object. 2920 VisitForStackValue(args->at(0)); // Load the object.
2840 VisitForAccumulatorValue(args->at(1)); // Load the value. 2921 VisitForAccumulatorValue(args->at(1)); // Load the value.
2841 __ pop(ebx); // eax = value. ebx = object. 2922 __ pop(ebx); // eax = value. ebx = object.
2923 decrement_stack_height();
2842 2924
2843 Label done; 2925 Label done;
2844 // If the object is a smi, return the value. 2926 // If the object is a smi, return the value.
2845 __ JumpIfSmi(ebx, &done, Label::kNear); 2927 __ JumpIfSmi(ebx, &done, Label::kNear);
2846 2928
2847 // If the object is not a value type, return the value. 2929 // If the object is not a value type, return the value.
2848 __ CmpObjectType(ebx, JS_VALUE_TYPE, ecx); 2930 __ CmpObjectType(ebx, JS_VALUE_TYPE, ecx);
2849 __ j(not_equal, &done, Label::kNear); 2931 __ j(not_equal, &done, Label::kNear);
2850 2932
2851 // Store the value. 2933 // Store the value.
(...skipping 10 matching lines...) Expand all
2862 2944
2863 2945
2864 void FullCodeGenerator::EmitNumberToString(ZoneList<Expression*>* args) { 2946 void FullCodeGenerator::EmitNumberToString(ZoneList<Expression*>* args) {
2865 ASSERT_EQ(args->length(), 1); 2947 ASSERT_EQ(args->length(), 1);
2866 2948
2867 // Load the argument on the stack and call the stub. 2949 // Load the argument on the stack and call the stub.
2868 VisitForStackValue(args->at(0)); 2950 VisitForStackValue(args->at(0));
2869 2951
2870 NumberToStringStub stub; 2952 NumberToStringStub stub;
2871 __ CallStub(&stub); 2953 __ CallStub(&stub);
2954 decrement_stack_height();
2872 context()->Plug(eax); 2955 context()->Plug(eax);
2873 } 2956 }
2874 2957
2875 2958
2876 void FullCodeGenerator::EmitStringCharFromCode(ZoneList<Expression*>* args) { 2959 void FullCodeGenerator::EmitStringCharFromCode(ZoneList<Expression*>* args) {
2877 ASSERT(args->length() == 1); 2960 ASSERT(args->length() == 1);
2878 2961
2879 VisitForAccumulatorValue(args->at(0)); 2962 VisitForAccumulatorValue(args->at(0));
2880 2963
2881 Label done; 2964 Label done;
(...skipping 14 matching lines...) Expand all
2896 2979
2897 VisitForStackValue(args->at(0)); 2980 VisitForStackValue(args->at(0));
2898 VisitForAccumulatorValue(args->at(1)); 2981 VisitForAccumulatorValue(args->at(1));
2899 2982
2900 Register object = ebx; 2983 Register object = ebx;
2901 Register index = eax; 2984 Register index = eax;
2902 Register scratch = ecx; 2985 Register scratch = ecx;
2903 Register result = edx; 2986 Register result = edx;
2904 2987
2905 __ pop(object); 2988 __ pop(object);
2989 decrement_stack_height();
2906 2990
2907 Label need_conversion; 2991 Label need_conversion;
2908 Label index_out_of_range; 2992 Label index_out_of_range;
2909 Label done; 2993 Label done;
2910 StringCharCodeAtGenerator generator(object, 2994 StringCharCodeAtGenerator generator(object,
2911 index, 2995 index,
2912 scratch, 2996 scratch,
2913 result, 2997 result,
2914 &need_conversion, 2998 &need_conversion,
2915 &need_conversion, 2999 &need_conversion,
(...skipping 28 matching lines...) Expand all
2944 VisitForStackValue(args->at(0)); 3028 VisitForStackValue(args->at(0));
2945 VisitForAccumulatorValue(args->at(1)); 3029 VisitForAccumulatorValue(args->at(1));
2946 3030
2947 Register object = ebx; 3031 Register object = ebx;
2948 Register index = eax; 3032 Register index = eax;
2949 Register scratch1 = ecx; 3033 Register scratch1 = ecx;
2950 Register scratch2 = edx; 3034 Register scratch2 = edx;
2951 Register result = eax; 3035 Register result = eax;
2952 3036
2953 __ pop(object); 3037 __ pop(object);
3038 decrement_stack_height();
2954 3039
2955 Label need_conversion; 3040 Label need_conversion;
2956 Label index_out_of_range; 3041 Label index_out_of_range;
2957 Label done; 3042 Label done;
2958 StringCharAtGenerator generator(object, 3043 StringCharAtGenerator generator(object,
2959 index, 3044 index,
2960 scratch1, 3045 scratch1,
2961 scratch2, 3046 scratch2,
2962 result, 3047 result,
2963 &need_conversion, 3048 &need_conversion,
(...skipping 24 matching lines...) Expand all
2988 3073
2989 3074
2990 void FullCodeGenerator::EmitStringAdd(ZoneList<Expression*>* args) { 3075 void FullCodeGenerator::EmitStringAdd(ZoneList<Expression*>* args) {
2991 ASSERT_EQ(2, args->length()); 3076 ASSERT_EQ(2, args->length());
2992 3077
2993 VisitForStackValue(args->at(0)); 3078 VisitForStackValue(args->at(0));
2994 VisitForStackValue(args->at(1)); 3079 VisitForStackValue(args->at(1));
2995 3080
2996 StringAddStub stub(NO_STRING_ADD_FLAGS); 3081 StringAddStub stub(NO_STRING_ADD_FLAGS);
2997 __ CallStub(&stub); 3082 __ CallStub(&stub);
3083 decrement_stack_height(2);
2998 context()->Plug(eax); 3084 context()->Plug(eax);
2999 } 3085 }
3000 3086
3001 3087
3002 void FullCodeGenerator::EmitStringCompare(ZoneList<Expression*>* args) { 3088 void FullCodeGenerator::EmitStringCompare(ZoneList<Expression*>* args) {
3003 ASSERT_EQ(2, args->length()); 3089 ASSERT_EQ(2, args->length());
3004 3090
3005 VisitForStackValue(args->at(0)); 3091 VisitForStackValue(args->at(0));
3006 VisitForStackValue(args->at(1)); 3092 VisitForStackValue(args->at(1));
3007 3093
3008 StringCompareStub stub; 3094 StringCompareStub stub;
3009 __ CallStub(&stub); 3095 __ CallStub(&stub);
3096 decrement_stack_height(2);
3010 context()->Plug(eax); 3097 context()->Plug(eax);
3011 } 3098 }
3012 3099
3013 3100
3014 void FullCodeGenerator::EmitMathSin(ZoneList<Expression*>* args) { 3101 void FullCodeGenerator::EmitMathSin(ZoneList<Expression*>* args) {
3015 // Load the argument on the stack and call the stub. 3102 // Load the argument on the stack and call the stub.
3016 TranscendentalCacheStub stub(TranscendentalCache::SIN, 3103 TranscendentalCacheStub stub(TranscendentalCache::SIN,
3017 TranscendentalCacheStub::TAGGED); 3104 TranscendentalCacheStub::TAGGED);
3018 ASSERT(args->length() == 1); 3105 ASSERT(args->length() == 1);
3019 VisitForStackValue(args->at(0)); 3106 VisitForStackValue(args->at(0));
3020 __ CallStub(&stub); 3107 __ CallStub(&stub);
3108 decrement_stack_height();
3021 context()->Plug(eax); 3109 context()->Plug(eax);
3022 } 3110 }
3023 3111
3024 3112
3025 void FullCodeGenerator::EmitMathCos(ZoneList<Expression*>* args) { 3113 void FullCodeGenerator::EmitMathCos(ZoneList<Expression*>* args) {
3026 // Load the argument on the stack and call the stub. 3114 // Load the argument on the stack and call the stub.
3027 TranscendentalCacheStub stub(TranscendentalCache::COS, 3115 TranscendentalCacheStub stub(TranscendentalCache::COS,
3028 TranscendentalCacheStub::TAGGED); 3116 TranscendentalCacheStub::TAGGED);
3029 ASSERT(args->length() == 1); 3117 ASSERT(args->length() == 1);
3030 VisitForStackValue(args->at(0)); 3118 VisitForStackValue(args->at(0));
3031 __ CallStub(&stub); 3119 __ CallStub(&stub);
3120 decrement_stack_height();
3032 context()->Plug(eax); 3121 context()->Plug(eax);
3033 } 3122 }
3034 3123
3035 3124
3036 void FullCodeGenerator::EmitMathLog(ZoneList<Expression*>* args) { 3125 void FullCodeGenerator::EmitMathLog(ZoneList<Expression*>* args) {
3037 // Load the argument on the stack and call the stub. 3126 // Load the argument on the stack and call the stub.
3038 TranscendentalCacheStub stub(TranscendentalCache::LOG, 3127 TranscendentalCacheStub stub(TranscendentalCache::LOG,
3039 TranscendentalCacheStub::TAGGED); 3128 TranscendentalCacheStub::TAGGED);
3040 ASSERT(args->length() == 1); 3129 ASSERT(args->length() == 1);
3041 VisitForStackValue(args->at(0)); 3130 VisitForStackValue(args->at(0));
3042 __ CallStub(&stub); 3131 __ CallStub(&stub);
3132 decrement_stack_height();
3043 context()->Plug(eax); 3133 context()->Plug(eax);
3044 } 3134 }
3045 3135
3046 3136
3047 void FullCodeGenerator::EmitMathSqrt(ZoneList<Expression*>* args) { 3137 void FullCodeGenerator::EmitMathSqrt(ZoneList<Expression*>* args) {
3048 // Load the argument on the stack and call the runtime function. 3138 // Load the argument on the stack and call the runtime function.
3049 ASSERT(args->length() == 1); 3139 ASSERT(args->length() == 1);
3050 VisitForStackValue(args->at(0)); 3140 VisitForStackValue(args->at(0));
3051 __ CallRuntime(Runtime::kMath_sqrt, 1); 3141 __ CallRuntime(Runtime::kMath_sqrt, 1);
3142 decrement_stack_height();
3052 context()->Plug(eax); 3143 context()->Plug(eax);
3053 } 3144 }
3054 3145
3055 3146
3056 void FullCodeGenerator::EmitCallFunction(ZoneList<Expression*>* args) { 3147 void FullCodeGenerator::EmitCallFunction(ZoneList<Expression*>* args) {
3057 ASSERT(args->length() >= 2); 3148 ASSERT(args->length() >= 2);
3058 3149
3059 int arg_count = args->length() - 2; // 2 ~ receiver and function. 3150 int arg_count = args->length() - 2; // 2 ~ receiver and function.
3060 for (int i = 0; i < arg_count + 1; ++i) { 3151 for (int i = 0; i < arg_count + 1; ++i) {
3061 VisitForStackValue(args->at(i)); 3152 VisitForStackValue(args->at(i));
3062 } 3153 }
3063 VisitForAccumulatorValue(args->last()); // Function. 3154 VisitForAccumulatorValue(args->last()); // Function.
3064 3155
3065 // InvokeFunction requires the function in edi. Move it in there. 3156 // InvokeFunction requires the function in edi. Move it in there.
3066 __ mov(edi, result_register()); 3157 __ mov(edi, result_register());
3067 ParameterCount count(arg_count); 3158 ParameterCount count(arg_count);
3068 __ InvokeFunction(edi, count, CALL_FUNCTION, 3159 __ InvokeFunction(edi, count, CALL_FUNCTION,
3069 NullCallWrapper(), CALL_AS_METHOD); 3160 NullCallWrapper(), CALL_AS_METHOD);
3070 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 3161 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
3162 decrement_stack_height(arg_count + 1);
3071 context()->Plug(eax); 3163 context()->Plug(eax);
3072 } 3164 }
3073 3165
3074 3166
3075 void FullCodeGenerator::EmitRegExpConstructResult(ZoneList<Expression*>* args) { 3167 void FullCodeGenerator::EmitRegExpConstructResult(ZoneList<Expression*>* args) {
3076 // Load the arguments on the stack and call the stub. 3168 // Load the arguments on the stack and call the stub.
3077 RegExpConstructResultStub stub; 3169 RegExpConstructResultStub stub;
3078 ASSERT(args->length() == 3); 3170 ASSERT(args->length() == 3);
3079 VisitForStackValue(args->at(0)); 3171 VisitForStackValue(args->at(0));
3080 VisitForStackValue(args->at(1)); 3172 VisitForStackValue(args->at(1));
3081 VisitForStackValue(args->at(2)); 3173 VisitForStackValue(args->at(2));
3082 __ CallStub(&stub); 3174 __ CallStub(&stub);
3175 decrement_stack_height(3);
3083 context()->Plug(eax); 3176 context()->Plug(eax);
3084 } 3177 }
3085 3178
3086 3179
3087 void FullCodeGenerator::EmitSwapElements(ZoneList<Expression*>* args) { 3180 void FullCodeGenerator::EmitSwapElements(ZoneList<Expression*>* args) {
3088 ASSERT(args->length() == 3); 3181 ASSERT(args->length() == 3);
3089 VisitForStackValue(args->at(0)); 3182 VisitForStackValue(args->at(0));
3090 VisitForStackValue(args->at(1)); 3183 VisitForStackValue(args->at(1));
3091 VisitForStackValue(args->at(2)); 3184 VisitForStackValue(args->at(2));
3092 Label done; 3185 Label done;
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
3159 3252
3160 // We are done. Drop elements from the stack, and return undefined. 3253 // We are done. Drop elements from the stack, and return undefined.
3161 __ add(Operand(esp), Immediate(3 * kPointerSize)); 3254 __ add(Operand(esp), Immediate(3 * kPointerSize));
3162 __ mov(eax, isolate()->factory()->undefined_value()); 3255 __ mov(eax, isolate()->factory()->undefined_value());
3163 __ jmp(&done); 3256 __ jmp(&done);
3164 3257
3165 __ bind(&slow_case); 3258 __ bind(&slow_case);
3166 __ CallRuntime(Runtime::kSwapElements, 3); 3259 __ CallRuntime(Runtime::kSwapElements, 3);
3167 3260
3168 __ bind(&done); 3261 __ bind(&done);
3262 decrement_stack_height(3);
3169 context()->Plug(eax); 3263 context()->Plug(eax);
3170 } 3264 }
3171 3265
3172 3266
3173 void FullCodeGenerator::EmitGetFromCache(ZoneList<Expression*>* args) { 3267 void FullCodeGenerator::EmitGetFromCache(ZoneList<Expression*>* args) {
3174 ASSERT_EQ(2, args->length()); 3268 ASSERT_EQ(2, args->length());
3175 3269
3176 ASSERT_NE(NULL, args->at(0)->AsLiteral()); 3270 ASSERT_NE(NULL, args->at(0)->AsLiteral());
3177 int cache_id = Smi::cast(*(args->at(0)->AsLiteral()->handle()))->value(); 3271 int cache_id = Smi::cast(*(args->at(0)->AsLiteral()->handle()))->value();
3178 3272
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
3244 __ mov(tmp, FieldOperand(left, JSRegExp::kDataOffset)); 3338 __ mov(tmp, FieldOperand(left, JSRegExp::kDataOffset));
3245 __ cmp(tmp, FieldOperand(right, JSRegExp::kDataOffset)); 3339 __ cmp(tmp, FieldOperand(right, JSRegExp::kDataOffset));
3246 __ j(equal, &ok); 3340 __ j(equal, &ok);
3247 __ bind(&fail); 3341 __ bind(&fail);
3248 __ mov(eax, Immediate(isolate()->factory()->false_value())); 3342 __ mov(eax, Immediate(isolate()->factory()->false_value()));
3249 __ jmp(&done); 3343 __ jmp(&done);
3250 __ bind(&ok); 3344 __ bind(&ok);
3251 __ mov(eax, Immediate(isolate()->factory()->true_value())); 3345 __ mov(eax, Immediate(isolate()->factory()->true_value()));
3252 __ bind(&done); 3346 __ bind(&done);
3253 3347
3348 decrement_stack_height();
3254 context()->Plug(eax); 3349 context()->Plug(eax);
3255 } 3350 }
3256 3351
3257 3352
3258 void FullCodeGenerator::EmitHasCachedArrayIndex(ZoneList<Expression*>* args) { 3353 void FullCodeGenerator::EmitHasCachedArrayIndex(ZoneList<Expression*>* args) {
3259 ASSERT(args->length() == 1); 3354 ASSERT(args->length() == 1);
3260 3355
3261 VisitForAccumulatorValue(args->at(0)); 3356 VisitForAccumulatorValue(args->at(0));
3262 3357
3263 if (FLAG_debug_code) { 3358 if (FLAG_debug_code) {
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after
3547 3642
3548 3643
3549 __ bind(&bailout); 3644 __ bind(&bailout);
3550 __ mov(result_operand, isolate()->factory()->undefined_value()); 3645 __ mov(result_operand, isolate()->factory()->undefined_value());
3551 __ bind(&done); 3646 __ bind(&done);
3552 __ mov(eax, result_operand); 3647 __ mov(eax, result_operand);
3553 // Drop temp values from the stack, and restore context register. 3648 // Drop temp values from the stack, and restore context register.
3554 __ add(Operand(esp), Immediate(3 * kPointerSize)); 3649 __ add(Operand(esp), Immediate(3 * kPointerSize));
3555 3650
3556 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 3651 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
3652 decrement_stack_height();
3557 context()->Plug(eax); 3653 context()->Plug(eax);
3558 } 3654 }
3559 3655
3560 3656
3561 void FullCodeGenerator::EmitIsNativeOrStrictMode(ZoneList<Expression*>* args) { 3657 void FullCodeGenerator::EmitIsNativeOrStrictMode(ZoneList<Expression*>* args) {
3562 ASSERT(args->length() == 1); 3658 ASSERT(args->length() == 1);
3563 3659
3564 // Load the function into eax. 3660 // Load the function into eax.
3565 VisitForAccumulatorValue(args->at(0)); 3661 VisitForAccumulatorValue(args->at(0));
3566 3662
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
3599 return; 3695 return;
3600 } 3696 }
3601 3697
3602 Comment cmnt(masm_, "[ CallRuntime"); 3698 Comment cmnt(masm_, "[ CallRuntime");
3603 ZoneList<Expression*>* args = expr->arguments(); 3699 ZoneList<Expression*>* args = expr->arguments();
3604 3700
3605 if (expr->is_jsruntime()) { 3701 if (expr->is_jsruntime()) {
3606 // Prepare for calling JS runtime function. 3702 // Prepare for calling JS runtime function.
3607 __ mov(eax, GlobalObjectOperand()); 3703 __ mov(eax, GlobalObjectOperand());
3608 __ push(FieldOperand(eax, GlobalObject::kBuiltinsOffset)); 3704 __ push(FieldOperand(eax, GlobalObject::kBuiltinsOffset));
3705 increment_stack_height();
3609 } 3706 }
3610 3707
3611 // Push the arguments ("left-to-right"). 3708 // Push the arguments ("left-to-right").
3612 int arg_count = args->length(); 3709 int arg_count = args->length();
3613 for (int i = 0; i < arg_count; i++) { 3710 for (int i = 0; i < arg_count; i++) {
3614 VisitForStackValue(args->at(i)); 3711 VisitForStackValue(args->at(i));
3615 } 3712 }
3616 3713
3617 if (expr->is_jsruntime()) { 3714 if (expr->is_jsruntime()) {
3618 // Call the JS runtime function via a call IC. 3715 // Call the JS runtime function via a call IC.
3619 __ Set(ecx, Immediate(expr->name())); 3716 __ Set(ecx, Immediate(expr->name()));
3620 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; 3717 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
3621 RelocInfo::Mode mode = RelocInfo::CODE_TARGET; 3718 RelocInfo::Mode mode = RelocInfo::CODE_TARGET;
3622 Handle<Code> ic = isolate()->stub_cache()->ComputeCallInitialize( 3719 Handle<Code> ic = isolate()->stub_cache()->ComputeCallInitialize(
3623 arg_count, in_loop, mode); 3720 arg_count, in_loop, mode);
3624 __ call(ic, mode, expr->id()); 3721 __ call(ic, mode, expr->id());
3625 // Restore context register. 3722 // Restore context register.
3626 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 3723 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
3627 } else { 3724 } else {
3628 // Call the C runtime function. 3725 // Call the C runtime function.
3629 __ CallRuntime(expr->function(), arg_count); 3726 __ CallRuntime(expr->function(), arg_count);
3630 } 3727 }
3728 decrement_stack_height(arg_count);
3729 if (expr->is_jsruntime()) {
3730 decrement_stack_height();
3731 }
3732
3631 context()->Plug(eax); 3733 context()->Plug(eax);
3632 } 3734 }
3633 3735
3634 3736
3635 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { 3737 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
3636 switch (expr->op()) { 3738 switch (expr->op()) {
3637 case Token::DELETE: { 3739 case Token::DELETE: {
3638 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); 3740 Comment cmnt(masm_, "[ UnaryOperation (DELETE)");
3639 Property* prop = expr->expression()->AsProperty(); 3741 Property* prop = expr->expression()->AsProperty();
3640 Variable* var = expr->expression()->AsVariableProxy()->AsVariable(); 3742 Variable* var = expr->expression()->AsVariableProxy()->AsVariable();
3641 3743
3642 if (prop != NULL) { 3744 if (prop != NULL) {
3643 if (prop->is_synthetic()) { 3745 if (prop->is_synthetic()) {
3644 // Result of deleting parameters is false, even when they rewrite 3746 // Result of deleting parameters is false, even when they rewrite
3645 // to accesses on the arguments object. 3747 // to accesses on the arguments object.
3646 context()->Plug(false); 3748 context()->Plug(false);
3647 } else { 3749 } else {
3648 VisitForStackValue(prop->obj()); 3750 VisitForStackValue(prop->obj());
3649 VisitForStackValue(prop->key()); 3751 VisitForStackValue(prop->key());
3650 __ push(Immediate(Smi::FromInt(strict_mode_flag()))); 3752 __ push(Immediate(Smi::FromInt(strict_mode_flag())));
3651 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); 3753 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
3754 decrement_stack_height(2);
3652 context()->Plug(eax); 3755 context()->Plug(eax);
3653 } 3756 }
3654 } else if (var != NULL) { 3757 } else if (var != NULL) {
3655 // Delete of an unqualified identifier is disallowed in strict mode 3758 // Delete of an unqualified identifier is disallowed in strict mode
3656 // but "delete this" is. 3759 // but "delete this" is.
3657 ASSERT(strict_mode_flag() == kNonStrictMode || var->is_this()); 3760 ASSERT(strict_mode_flag() == kNonStrictMode || var->is_this());
3658 if (var->is_global()) { 3761 if (var->is_global()) {
3659 __ push(GlobalObjectOperand()); 3762 __ push(GlobalObjectOperand());
3660 __ push(Immediate(var->name())); 3763 __ push(Immediate(var->name()));
3661 __ push(Immediate(Smi::FromInt(kNonStrictMode))); 3764 __ push(Immediate(Smi::FromInt(kNonStrictMode)));
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
3711 } 3814 }
3712 break; 3815 break;
3713 } 3816 }
3714 3817
3715 case Token::TYPEOF: { 3818 case Token::TYPEOF: {
3716 Comment cmnt(masm_, "[ UnaryOperation (TYPEOF)"); 3819 Comment cmnt(masm_, "[ UnaryOperation (TYPEOF)");
3717 { StackValueContext context(this); 3820 { StackValueContext context(this);
3718 VisitForTypeofValue(expr->expression()); 3821 VisitForTypeofValue(expr->expression());
3719 } 3822 }
3720 __ CallRuntime(Runtime::kTypeof, 1); 3823 __ CallRuntime(Runtime::kTypeof, 1);
3824 decrement_stack_height();
3721 context()->Plug(eax); 3825 context()->Plug(eax);
3722 break; 3826 break;
3723 } 3827 }
3724 3828
3725 case Token::ADD: { 3829 case Token::ADD: {
3726 Comment cmt(masm_, "[ UnaryOperation (ADD)"); 3830 Comment cmt(masm_, "[ UnaryOperation (ADD)");
3727 VisitForAccumulatorValue(expr->expression()); 3831 VisitForAccumulatorValue(expr->expression());
3728 Label no_conversion; 3832 Label no_conversion;
3729 __ JumpIfSmi(result_register(), &no_conversion); 3833 __ JumpIfSmi(result_register(), &no_conversion);
3730 ToNumberStub convert_stub; 3834 ToNumberStub convert_stub;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
3765 } 3869 }
3766 3870
3767 3871
3768 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { 3872 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
3769 Comment cmnt(masm_, "[ CountOperation"); 3873 Comment cmnt(masm_, "[ CountOperation");
3770 SetSourcePosition(expr->position()); 3874 SetSourcePosition(expr->position());
3771 3875
3772 // Invalid left-hand sides are rewritten to have a 'throw ReferenceError' 3876 // Invalid left-hand sides are rewritten to have a 'throw ReferenceError'
3773 // as the left-hand side. 3877 // as the left-hand side.
3774 if (!expr->expression()->IsValidLeftHandSide()) { 3878 if (!expr->expression()->IsValidLeftHandSide()) {
3775 VisitForEffect(expr->expression()); 3879 ASSERT(expr->expression()->AsThrow() != NULL);
3880 VisitInCurrentContext(expr->expression());
3881 // Visiting Throw does not plug the context.
3882 context()->Plug(eax);
3776 return; 3883 return;
3777 } 3884 }
3778 3885
3779 // Expression can only be a property, a global or a (parameter or local) 3886 // Expression can only be a property, a global or a (parameter or local)
3780 // slot. 3887 // slot.
3781 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; 3888 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
3782 LhsKind assign_type = VARIABLE; 3889 LhsKind assign_type = VARIABLE;
3783 Property* prop = expr->expression()->AsProperty(); 3890 Property* prop = expr->expression()->AsProperty();
3784 // In case of a property we use the uninitialized expression context 3891 // In case of a property we use the uninitialized expression context
3785 // of the key to detect a named property. 3892 // of the key to detect a named property.
3786 if (prop != NULL) { 3893 if (prop != NULL) {
3787 assign_type = 3894 assign_type =
3788 (prop->key()->IsPropertyName()) ? NAMED_PROPERTY : KEYED_PROPERTY; 3895 (prop->key()->IsPropertyName()) ? NAMED_PROPERTY : KEYED_PROPERTY;
3789 } 3896 }
3790 3897
3791 // Evaluate expression and get value. 3898 // Evaluate expression and get value.
3792 if (assign_type == VARIABLE) { 3899 if (assign_type == VARIABLE) {
3793 ASSERT(expr->expression()->AsVariableProxy()->var() != NULL); 3900 ASSERT(expr->expression()->AsVariableProxy()->var() != NULL);
3794 AccumulatorValueContext context(this); 3901 AccumulatorValueContext context(this);
3795 EmitVariableLoad(expr->expression()->AsVariableProxy()->var()); 3902 EmitVariableLoad(expr->expression()->AsVariableProxy());
3796 } else { 3903 } else {
3797 // Reserve space for result of postfix operation. 3904 // Reserve space for result of postfix operation.
3798 if (expr->is_postfix() && !context()->IsEffect()) { 3905 if (expr->is_postfix() && !context()->IsEffect()) {
3799 __ push(Immediate(Smi::FromInt(0))); 3906 __ push(Immediate(Smi::FromInt(0)));
3907 increment_stack_height();
3800 } 3908 }
3801 if (assign_type == NAMED_PROPERTY) { 3909 if (assign_type == NAMED_PROPERTY) {
3802 // Put the object both on the stack and in the accumulator. 3910 // Put the object both on the stack and in the accumulator.
3803 VisitForAccumulatorValue(prop->obj()); 3911 VisitForAccumulatorValue(prop->obj());
3804 __ push(eax); 3912 __ push(eax);
3913 increment_stack_height();
3805 EmitNamedPropertyLoad(prop); 3914 EmitNamedPropertyLoad(prop);
3806 } else { 3915 } else {
3807 VisitForStackValue(prop->obj()); 3916 VisitForStackValue(prop->obj());
3808 VisitForAccumulatorValue(prop->key()); 3917 VisitForAccumulatorValue(prop->key());
3809 __ mov(edx, Operand(esp, 0)); 3918 __ mov(edx, Operand(esp, 0));
3810 __ push(eax); 3919 __ push(eax);
3920 increment_stack_height();
3811 EmitKeyedPropertyLoad(prop); 3921 EmitKeyedPropertyLoad(prop);
3812 } 3922 }
3813 } 3923 }
3814 3924
3815 // We need a second deoptimization point after loading the value 3925 // We need a second deoptimization point after loading the value
3816 // in case evaluating the property load my have a side effect. 3926 // in case evaluating the property load my have a side effect.
3817 if (assign_type == VARIABLE) { 3927 if (assign_type == VARIABLE) {
3818 PrepareForBailout(expr->expression(), TOS_REG); 3928 PrepareForBailout(expr->expression(), TOS_REG);
3819 } else { 3929 } else {
3820 PrepareForBailoutForId(expr->CountId(), TOS_REG); 3930 PrepareForBailoutForId(expr->CountId(), TOS_REG);
(...skipping 10 matching lines...) Expand all
3831 3941
3832 // Save result for postfix expressions. 3942 // Save result for postfix expressions.
3833 if (expr->is_postfix()) { 3943 if (expr->is_postfix()) {
3834 if (!context()->IsEffect()) { 3944 if (!context()->IsEffect()) {
3835 // Save the result on the stack. If we have a named or keyed property 3945 // Save the result on the stack. If we have a named or keyed property
3836 // we store the result under the receiver that is currently on top 3946 // we store the result under the receiver that is currently on top
3837 // of the stack. 3947 // of the stack.
3838 switch (assign_type) { 3948 switch (assign_type) {
3839 case VARIABLE: 3949 case VARIABLE:
3840 __ push(eax); 3950 __ push(eax);
3951 increment_stack_height();
3841 break; 3952 break;
3842 case NAMED_PROPERTY: 3953 case NAMED_PROPERTY:
3843 __ mov(Operand(esp, kPointerSize), eax); 3954 __ mov(Operand(esp, kPointerSize), eax);
3844 break; 3955 break;
3845 case KEYED_PROPERTY: 3956 case KEYED_PROPERTY:
3846 __ mov(Operand(esp, 2 * kPointerSize), eax); 3957 __ mov(Operand(esp, 2 * kPointerSize), eax);
3847 break; 3958 break;
3848 } 3959 }
3849 } 3960 }
3850 } 3961 }
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
3904 // Perform the assignment as if via '='. 4015 // Perform the assignment as if via '='.
3905 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 4016 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
3906 Token::ASSIGN); 4017 Token::ASSIGN);
3907 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4018 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3908 context()->Plug(eax); 4019 context()->Plug(eax);
3909 } 4020 }
3910 break; 4021 break;
3911 case NAMED_PROPERTY: { 4022 case NAMED_PROPERTY: {
3912 __ mov(ecx, prop->key()->AsLiteral()->handle()); 4023 __ mov(ecx, prop->key()->AsLiteral()->handle());
3913 __ pop(edx); 4024 __ pop(edx);
4025 decrement_stack_height();
3914 Handle<Code> ic = is_strict_mode() 4026 Handle<Code> ic = is_strict_mode()
3915 ? isolate()->builtins()->StoreIC_Initialize_Strict() 4027 ? isolate()->builtins()->StoreIC_Initialize_Strict()
3916 : isolate()->builtins()->StoreIC_Initialize(); 4028 : isolate()->builtins()->StoreIC_Initialize();
3917 __ call(ic, RelocInfo::CODE_TARGET, expr->id()); 4029 __ call(ic, RelocInfo::CODE_TARGET, expr->id());
3918 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4030 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3919 if (expr->is_postfix()) { 4031 if (expr->is_postfix()) {
3920 if (!context()->IsEffect()) { 4032 if (!context()->IsEffect()) {
3921 context()->PlugTOS(); 4033 context()->PlugTOS();
3922 } 4034 }
3923 } else { 4035 } else {
3924 context()->Plug(eax); 4036 context()->Plug(eax);
3925 } 4037 }
3926 break; 4038 break;
3927 } 4039 }
3928 case KEYED_PROPERTY: { 4040 case KEYED_PROPERTY: {
3929 __ pop(ecx); 4041 __ pop(ecx);
3930 __ pop(edx); 4042 __ pop(edx);
4043 decrement_stack_height();
4044 decrement_stack_height();
3931 Handle<Code> ic = is_strict_mode() 4045 Handle<Code> ic = is_strict_mode()
3932 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 4046 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
3933 : isolate()->builtins()->KeyedStoreIC_Initialize(); 4047 : isolate()->builtins()->KeyedStoreIC_Initialize();
3934 __ call(ic, RelocInfo::CODE_TARGET, expr->id()); 4048 __ call(ic, RelocInfo::CODE_TARGET, expr->id());
3935 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4049 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3936 if (expr->is_postfix()) { 4050 if (expr->is_postfix()) {
3937 // Result is on the stack 4051 // Result is on the stack
3938 if (!context()->IsEffect()) { 4052 if (!context()->IsEffect()) {
3939 context()->PlugTOS(); 4053 context()->PlugTOS();
3940 } 4054 }
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
4078 context()->Plug(if_true, if_false); 4192 context()->Plug(if_true, if_false);
4079 return; 4193 return;
4080 } 4194 }
4081 4195
4082 Token::Value op = expr->op(); 4196 Token::Value op = expr->op();
4083 VisitForStackValue(expr->left()); 4197 VisitForStackValue(expr->left());
4084 switch (expr->op()) { 4198 switch (expr->op()) {
4085 case Token::IN: 4199 case Token::IN:
4086 VisitForStackValue(expr->right()); 4200 VisitForStackValue(expr->right());
4087 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION); 4201 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION);
4202 decrement_stack_height(2);
4088 PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL); 4203 PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL);
4089 __ cmp(eax, isolate()->factory()->true_value()); 4204 __ cmp(eax, isolate()->factory()->true_value());
4090 Split(equal, if_true, if_false, fall_through); 4205 Split(equal, if_true, if_false, fall_through);
4091 break; 4206 break;
4092 4207
4093 case Token::INSTANCEOF: { 4208 case Token::INSTANCEOF: {
4094 VisitForStackValue(expr->right()); 4209 VisitForStackValue(expr->right());
4095 InstanceofStub stub(InstanceofStub::kNoFlags); 4210 InstanceofStub stub(InstanceofStub::kNoFlags);
4096 __ CallStub(&stub); 4211 __ CallStub(&stub);
4212 decrement_stack_height(2);
4097 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); 4213 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
4098 __ test(eax, Operand(eax)); 4214 __ test(eax, Operand(eax));
4099 // The stub returns 0 for true. 4215 // The stub returns 0 for true.
4100 Split(zero, if_true, if_false, fall_through); 4216 Split(zero, if_true, if_false, fall_through);
4101 break; 4217 break;
4102 } 4218 }
4103 4219
4104 default: { 4220 default: {
4105 VisitForAccumulatorValue(expr->right()); 4221 VisitForAccumulatorValue(expr->right());
4106 Condition cc = no_condition; 4222 Condition cc = no_condition;
(...skipping 24 matching lines...) Expand all
4131 break; 4247 break;
4132 case Token::GTE: 4248 case Token::GTE:
4133 cc = greater_equal; 4249 cc = greater_equal;
4134 __ pop(edx); 4250 __ pop(edx);
4135 break; 4251 break;
4136 case Token::IN: 4252 case Token::IN:
4137 case Token::INSTANCEOF: 4253 case Token::INSTANCEOF:
4138 default: 4254 default:
4139 UNREACHABLE(); 4255 UNREACHABLE();
4140 } 4256 }
4257 decrement_stack_height();
4141 4258
4142 bool inline_smi_code = ShouldInlineSmiCase(op); 4259 bool inline_smi_code = ShouldInlineSmiCase(op);
4143 JumpPatchSite patch_site(masm_); 4260 JumpPatchSite patch_site(masm_);
4144 if (inline_smi_code) { 4261 if (inline_smi_code) {
4145 Label slow_case; 4262 Label slow_case;
4146 __ mov(ecx, Operand(edx)); 4263 __ mov(ecx, Operand(edx));
4147 __ or_(ecx, Operand(eax)); 4264 __ or_(ecx, Operand(eax));
4148 patch_site.EmitJumpIfNotSmi(ecx, &slow_case, Label::kNear); 4265 patch_site.EmitJumpIfNotSmi(ecx, &slow_case, Label::kNear);
4149 __ cmp(edx, Operand(eax)); 4266 __ cmp(edx, Operand(eax));
4150 Split(cc, if_true, if_false, NULL); 4267 Split(cc, if_true, if_false, NULL);
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
4271 __ add(Operand(edx), Immediate(masm_->CodeObject())); 4388 __ add(Operand(edx), Immediate(masm_->CodeObject()));
4272 __ jmp(Operand(edx)); 4389 __ jmp(Operand(edx));
4273 } 4390 }
4274 4391
4275 4392
4276 #undef __ 4393 #undef __
4277 4394
4278 } } // namespace v8::internal 4395 } } // namespace v8::internal
4279 4396
4280 #endif // V8_TARGET_ARCH_IA32 4397 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/cpu-ia32.cc ('k') | src/ia32/lithium-codegen-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698