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

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

Issue 8340023: Remove stack height tracking from ia32 non-optimizing code generator. Reverts change 8755. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/full-codegen.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
162 if (locals_count == 1) { 162 if (locals_count == 1) {
163 __ push(Immediate(isolate()->factory()->undefined_value())); 163 __ push(Immediate(isolate()->factory()->undefined_value()));
164 } else if (locals_count > 1) { 164 } else if (locals_count > 1) {
165 __ mov(eax, Immediate(isolate()->factory()->undefined_value())); 165 __ mov(eax, Immediate(isolate()->factory()->undefined_value()));
166 for (int i = 0; i < locals_count; i++) { 166 for (int i = 0; i < locals_count; i++) {
167 __ push(eax); 167 __ push(eax);
168 } 168 }
169 } 169 }
170 } 170 }
171 171
172 set_stack_height(2 + scope()->num_stack_slots());
173 if (FLAG_verify_stack_height) {
174 verify_stack_height();
175 }
176
177 bool function_in_register = true; 172 bool function_in_register = true;
178 173
179 // Possibly allocate a local context. 174 // Possibly allocate a local context.
180 int heap_slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; 175 int heap_slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
181 if (heap_slots > 0) { 176 if (heap_slots > 0) {
182 Comment cmnt(masm_, "[ Allocate local context"); 177 Comment cmnt(masm_, "[ Allocate local context");
183 // Argument to NewContext is the function, which is still in edi. 178 // Argument to NewContext is the function, which is still in edi.
184 __ push(edi); 179 __ push(edi);
185 if (heap_slots <= FastNewContextStub::kMaximumSlots) { 180 if (heap_slots <= FastNewContextStub::kMaximumSlots) {
186 FastNewContextStub stub(heap_slots); 181 FastNewContextStub stub(heap_slots);
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
365 #ifdef ENABLE_DEBUGGER_SUPPORT 360 #ifdef ENABLE_DEBUGGER_SUPPORT
366 // Check that the size of the code used for returning is large enough 361 // Check that the size of the code used for returning is large enough
367 // for the debugger's requirements. 362 // for the debugger's requirements.
368 ASSERT(Assembler::kJSReturnSequenceLength <= 363 ASSERT(Assembler::kJSReturnSequenceLength <=
369 masm_->SizeOfCodeGeneratedSince(&check_exit_codesize)); 364 masm_->SizeOfCodeGeneratedSince(&check_exit_codesize));
370 #endif 365 #endif
371 } 366 }
372 } 367 }
373 368
374 369
375 void FullCodeGenerator::verify_stack_height() {
376 ASSERT(FLAG_verify_stack_height);
377 __ sub(ebp, Immediate(kPointerSize * stack_height()));
378 __ cmp(ebp, esp);
379 __ Assert(equal, "Full codegen stack height not as expected.");
380 __ add(ebp, Immediate(kPointerSize * stack_height()));
381 }
382
383
384 void FullCodeGenerator::EffectContext::Plug(Variable* var) const { 370 void FullCodeGenerator::EffectContext::Plug(Variable* var) const {
385 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); 371 ASSERT(var->IsStackAllocated() || var->IsContextSlot());
386 } 372 }
387 373
388 374
389 void FullCodeGenerator::AccumulatorValueContext::Plug(Variable* var) const { 375 void FullCodeGenerator::AccumulatorValueContext::Plug(Variable* var) const {
390 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); 376 ASSERT(var->IsStackAllocated() || var->IsContextSlot());
391 codegen()->GetVar(result_register(), var); 377 codegen()->GetVar(result_register(), var);
392 } 378 }
393 379
394 380
395 void FullCodeGenerator::StackValueContext::Plug(Variable* var) const { 381 void FullCodeGenerator::StackValueContext::Plug(Variable* var) const {
396 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); 382 ASSERT(var->IsStackAllocated() || var->IsContextSlot());
397 MemOperand operand = codegen()->VarOperand(var, result_register()); 383 MemOperand operand = codegen()->VarOperand(var, result_register());
398 // Memory operands can be pushed directly. 384 // Memory operands can be pushed directly.
399 __ push(operand); 385 __ push(operand);
400 codegen()->increment_stack_height();
401 } 386 }
402 387
403 388
404 void FullCodeGenerator::TestContext::Plug(Variable* var) const { 389 void FullCodeGenerator::TestContext::Plug(Variable* var) const {
405 // For simplicity we always test the accumulator register. 390 // For simplicity we always test the accumulator register.
406 codegen()->GetVar(result_register(), var); 391 codegen()->GetVar(result_register(), var);
407 codegen()->PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL); 392 codegen()->PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL);
408 codegen()->DoTest(this); 393 codegen()->DoTest(this);
409 } 394 }
410 395
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
444 } 429 }
445 } 430 }
446 431
447 432
448 void FullCodeGenerator::StackValueContext::Plug(Handle<Object> lit) const { 433 void FullCodeGenerator::StackValueContext::Plug(Handle<Object> lit) const {
449 if (lit->IsSmi()) { 434 if (lit->IsSmi()) {
450 __ SafePush(Immediate(lit)); 435 __ SafePush(Immediate(lit));
451 } else { 436 } else {
452 __ push(Immediate(lit)); 437 __ push(Immediate(lit));
453 } 438 }
454 codegen()->increment_stack_height();
455 } 439 }
456 440
457 441
458 void FullCodeGenerator::TestContext::Plug(Handle<Object> lit) const { 442 void FullCodeGenerator::TestContext::Plug(Handle<Object> lit) const {
459 codegen()->PrepareForBailoutBeforeSplit(TOS_REG, 443 codegen()->PrepareForBailoutBeforeSplit(TOS_REG,
460 true, 444 true,
461 true_label_, 445 true_label_,
462 false_label_); 446 false_label_);
463 ASSERT(!lit->IsUndetectableObject()); // There are no undetectable literals. 447 ASSERT(!lit->IsUndetectableObject()); // There are no undetectable literals.
464 if (lit->IsUndefined() || lit->IsNull() || lit->IsFalse()) { 448 if (lit->IsUndefined() || lit->IsNull() || lit->IsFalse()) {
(...skipping 17 matching lines...) Expand all
482 __ mov(result_register(), lit); 466 __ mov(result_register(), lit);
483 codegen()->DoTest(this); 467 codegen()->DoTest(this);
484 } 468 }
485 } 469 }
486 470
487 471
488 void FullCodeGenerator::EffectContext::DropAndPlug(int count, 472 void FullCodeGenerator::EffectContext::DropAndPlug(int count,
489 Register reg) const { 473 Register reg) const {
490 ASSERT(count > 0); 474 ASSERT(count > 0);
491 __ Drop(count); 475 __ Drop(count);
492 codegen()->decrement_stack_height(count);
493 } 476 }
494 477
495 478
496 void FullCodeGenerator::AccumulatorValueContext::DropAndPlug( 479 void FullCodeGenerator::AccumulatorValueContext::DropAndPlug(
497 int count, 480 int count,
498 Register reg) const { 481 Register reg) const {
499 ASSERT(count > 0); 482 ASSERT(count > 0);
500 __ Drop(count); 483 __ Drop(count);
501 __ Move(result_register(), reg); 484 __ Move(result_register(), reg);
502 codegen()->decrement_stack_height(count);
503 } 485 }
504 486
505 487
506 void FullCodeGenerator::StackValueContext::DropAndPlug(int count, 488 void FullCodeGenerator::StackValueContext::DropAndPlug(int count,
507 Register reg) const { 489 Register reg) const {
508 ASSERT(count > 0); 490 ASSERT(count > 0);
509 if (count > 1) __ Drop(count - 1); 491 if (count > 1) __ Drop(count - 1);
510 __ mov(Operand(esp, 0), reg); 492 __ mov(Operand(esp, 0), reg);
511 codegen()->decrement_stack_height(count - 1);
512 } 493 }
513 494
514 495
515 void FullCodeGenerator::TestContext::DropAndPlug(int count, 496 void FullCodeGenerator::TestContext::DropAndPlug(int count,
516 Register reg) const { 497 Register reg) const {
517 ASSERT(count > 0); 498 ASSERT(count > 0);
518 // For simplicity we always test the accumulator register. 499 // For simplicity we always test the accumulator register.
519 __ Drop(count); 500 __ Drop(count);
520 __ Move(result_register(), reg); 501 __ Move(result_register(), reg);
521 codegen()->PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL); 502 codegen()->PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL);
522 codegen()->DoTest(this); 503 codegen()->DoTest(this);
523 codegen()->decrement_stack_height(count);
524 } 504 }
525 505
526 506
527 void FullCodeGenerator::EffectContext::Plug(Label* materialize_true, 507 void FullCodeGenerator::EffectContext::Plug(Label* materialize_true,
528 Label* materialize_false) const { 508 Label* materialize_false) const {
529 ASSERT(materialize_true == materialize_false); 509 ASSERT(materialize_true == materialize_false);
530 __ bind(materialize_true); 510 __ bind(materialize_true);
531 } 511 }
532 512
533 513
(...skipping 13 matching lines...) Expand all
547 void FullCodeGenerator::StackValueContext::Plug( 527 void FullCodeGenerator::StackValueContext::Plug(
548 Label* materialize_true, 528 Label* materialize_true,
549 Label* materialize_false) const { 529 Label* materialize_false) const {
550 Label done; 530 Label done;
551 __ bind(materialize_true); 531 __ bind(materialize_true);
552 __ push(Immediate(isolate()->factory()->true_value())); 532 __ push(Immediate(isolate()->factory()->true_value()));
553 __ jmp(&done, Label::kNear); 533 __ jmp(&done, Label::kNear);
554 __ bind(materialize_false); 534 __ bind(materialize_false);
555 __ push(Immediate(isolate()->factory()->false_value())); 535 __ push(Immediate(isolate()->factory()->false_value()));
556 __ bind(&done); 536 __ bind(&done);
557 codegen()->increment_stack_height();
558 } 537 }
559 538
560 539
561 void FullCodeGenerator::TestContext::Plug(Label* materialize_true, 540 void FullCodeGenerator::TestContext::Plug(Label* materialize_true,
562 Label* materialize_false) const { 541 Label* materialize_false) const {
563 ASSERT(materialize_true == true_label_); 542 ASSERT(materialize_true == true_label_);
564 ASSERT(materialize_false == false_label_); 543 ASSERT(materialize_false == false_label_);
565 } 544 }
566 545
567 546
568 void FullCodeGenerator::EffectContext::Plug(bool flag) const { 547 void FullCodeGenerator::EffectContext::Plug(bool flag) const {
569 } 548 }
570 549
571 550
572 void FullCodeGenerator::AccumulatorValueContext::Plug(bool flag) const { 551 void FullCodeGenerator::AccumulatorValueContext::Plug(bool flag) const {
573 Handle<Object> value = flag 552 Handle<Object> value = flag
574 ? isolate()->factory()->true_value() 553 ? isolate()->factory()->true_value()
575 : isolate()->factory()->false_value(); 554 : isolate()->factory()->false_value();
576 __ mov(result_register(), value); 555 __ mov(result_register(), value);
577 } 556 }
578 557
579 558
580 void FullCodeGenerator::StackValueContext::Plug(bool flag) const { 559 void FullCodeGenerator::StackValueContext::Plug(bool flag) const {
581 Handle<Object> value = flag 560 Handle<Object> value = flag
582 ? isolate()->factory()->true_value() 561 ? isolate()->factory()->true_value()
583 : isolate()->factory()->false_value(); 562 : isolate()->factory()->false_value();
584 __ push(Immediate(value)); 563 __ push(Immediate(value));
585 codegen()->increment_stack_height();
586 } 564 }
587 565
588 566
589 void FullCodeGenerator::TestContext::Plug(bool flag) const { 567 void FullCodeGenerator::TestContext::Plug(bool flag) const {
590 codegen()->PrepareForBailoutBeforeSplit(TOS_REG, 568 codegen()->PrepareForBailoutBeforeSplit(TOS_REG,
591 true, 569 true,
592 true_label_, 570 true_label_,
593 false_label_); 571 false_label_);
594 if (flag) { 572 if (flag) {
595 if (true_label_ != fall_through_) __ jmp(true_label_); 573 if (true_label_ != fall_through_) __ jmp(true_label_);
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
777 mode == CONST || 755 mode == CONST ||
778 mode == CONST_HARMONY || 756 mode == CONST_HARMONY ||
779 mode == LET); 757 mode == LET);
780 PropertyAttributes attr = (mode == CONST || mode == CONST_HARMONY) 758 PropertyAttributes attr = (mode == CONST || mode == CONST_HARMONY)
781 ? READ_ONLY : NONE; 759 ? READ_ONLY : NONE;
782 __ push(Immediate(Smi::FromInt(attr))); 760 __ push(Immediate(Smi::FromInt(attr)));
783 // Push initial value, if any. 761 // Push initial value, if any.
784 // Note: For variables we must not push an initial value (such as 762 // Note: For variables we must not push an initial value (such as
785 // 'undefined') because we may have a (legal) redeclaration and we 763 // 'undefined') because we may have a (legal) redeclaration and we
786 // must not destroy the current value. 764 // must not destroy the current value.
787 increment_stack_height(3);
788 if (function != NULL) { 765 if (function != NULL) {
789 VisitForStackValue(function); 766 VisitForStackValue(function);
790 } else if (binding_needs_init) { 767 } else if (binding_needs_init) {
791 __ push(Immediate(isolate()->factory()->the_hole_value())); 768 __ push(Immediate(isolate()->factory()->the_hole_value()));
792 increment_stack_height();
793 } else { 769 } else {
794 __ push(Immediate(Smi::FromInt(0))); // Indicates no initial value. 770 __ push(Immediate(Smi::FromInt(0))); // Indicates no initial value.
795 increment_stack_height();
796 } 771 }
797 __ CallRuntime(Runtime::kDeclareContextSlot, 4); 772 __ CallRuntime(Runtime::kDeclareContextSlot, 4);
798 decrement_stack_height(4);
799 break; 773 break;
800 } 774 }
801 } 775 }
802 } 776 }
803 777
804 778
805 void FullCodeGenerator::VisitDeclaration(Declaration* decl) { } 779 void FullCodeGenerator::VisitDeclaration(Declaration* decl) { }
806 780
807 781
808 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { 782 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
809 // Call the runtime to declare the globals. 783 // Call the runtime to declare the globals.
810 __ push(esi); // The context is the first argument. 784 __ push(esi); // The context is the first argument.
811 __ push(Immediate(pairs)); 785 __ push(Immediate(pairs));
812 __ push(Immediate(Smi::FromInt(DeclareGlobalsFlags()))); 786 __ push(Immediate(Smi::FromInt(DeclareGlobalsFlags())));
813 __ CallRuntime(Runtime::kDeclareGlobals, 3); 787 __ CallRuntime(Runtime::kDeclareGlobals, 3);
814 // Return value is ignored. 788 // Return value is ignored.
815 } 789 }
816 790
817 791
818 void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { 792 void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
819 Comment cmnt(masm_, "[ SwitchStatement"); 793 Comment cmnt(masm_, "[ SwitchStatement");
820 Breakable nested_statement(this, stmt); 794 Breakable nested_statement(this, stmt);
821 SetStatementPosition(stmt); 795 SetStatementPosition(stmt);
822 796
823 int switch_clause_stack_height = stack_height();
824 // Keep the switch value on the stack until a case matches. 797 // Keep the switch value on the stack until a case matches.
825 VisitForStackValue(stmt->tag()); 798 VisitForStackValue(stmt->tag());
826 PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS); 799 PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS);
827 800
828 ZoneList<CaseClause*>* clauses = stmt->cases(); 801 ZoneList<CaseClause*>* clauses = stmt->cases();
829 CaseClause* default_clause = NULL; // Can occur anywhere in the list. 802 CaseClause* default_clause = NULL; // Can occur anywhere in the list.
830 803
831 Label next_test; // Recycled for each test. 804 Label next_test; // Recycled for each test.
832 // Compile all the tests with branches to their bodies. 805 // Compile all the tests with branches to their bodies.
833 for (int i = 0; i < clauses->length(); i++) { 806 for (int i = 0; i < clauses->length(); i++) {
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
878 // Discard the test value and jump to the default if present, otherwise to 851 // Discard the test value and jump to the default if present, otherwise to
879 // the end of the statement. 852 // the end of the statement.
880 __ bind(&next_test); 853 __ bind(&next_test);
881 __ Drop(1); // Switch value is no longer needed. 854 __ Drop(1); // Switch value is no longer needed.
882 if (default_clause == NULL) { 855 if (default_clause == NULL) {
883 __ jmp(nested_statement.break_label()); 856 __ jmp(nested_statement.break_label());
884 } else { 857 } else {
885 __ jmp(default_clause->body_target()); 858 __ jmp(default_clause->body_target());
886 } 859 }
887 860
888 set_stack_height(switch_clause_stack_height);
889 // Compile all the case bodies. 861 // Compile all the case bodies.
890 for (int i = 0; i < clauses->length(); i++) { 862 for (int i = 0; i < clauses->length(); i++) {
891 Comment cmnt(masm_, "[ Case body"); 863 Comment cmnt(masm_, "[ Case body");
892 CaseClause* clause = clauses->at(i); 864 CaseClause* clause = clauses->at(i);
893 __ bind(clause->body_target()); 865 __ bind(clause->body_target());
894 PrepareForBailoutForId(clause->EntryId(), NO_REGISTERS); 866 PrepareForBailoutForId(clause->EntryId(), NO_REGISTERS);
895 VisitStatements(clause->statements()); 867 VisitStatements(clause->statements());
896 } 868 }
897 869
898 __ bind(nested_statement.break_label()); 870 __ bind(nested_statement.break_label());
(...skipping 21 matching lines...) Expand all
920 // Convert the object to a JS object. 892 // Convert the object to a JS object.
921 Label convert, done_convert; 893 Label convert, done_convert;
922 __ JumpIfSmi(eax, &convert, Label::kNear); 894 __ JumpIfSmi(eax, &convert, Label::kNear);
923 __ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, ecx); 895 __ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, ecx);
924 __ j(above_equal, &done_convert, Label::kNear); 896 __ j(above_equal, &done_convert, Label::kNear);
925 __ bind(&convert); 897 __ bind(&convert);
926 __ push(eax); 898 __ push(eax);
927 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION); 899 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
928 __ bind(&done_convert); 900 __ bind(&done_convert);
929 __ push(eax); 901 __ push(eax);
930 increment_stack_height();
931 902
932 // Check for proxies. 903 // Check for proxies.
933 Label call_runtime; 904 Label call_runtime;
934 STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE); 905 STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE);
935 __ CmpObjectType(eax, LAST_JS_PROXY_TYPE, ecx); 906 __ CmpObjectType(eax, LAST_JS_PROXY_TYPE, ecx);
936 __ j(below_equal, &call_runtime); 907 __ j(below_equal, &call_runtime);
937 908
938 // Check cache validity in generated code. This is a fast case for 909 // Check cache validity in generated code. This is a fast case for
939 // the JSObject::IsSimpleEnum cache validity checks. If we cannot 910 // the JSObject::IsSimpleEnum cache validity checks. If we cannot
940 // guarantee cache validity, call the runtime system to check cache 911 // guarantee cache validity, call the runtime system to check cache
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
1018 __ CmpObjectType(ecx, LAST_JS_PROXY_TYPE, ecx); 989 __ CmpObjectType(ecx, LAST_JS_PROXY_TYPE, ecx);
1019 __ j(above, &non_proxy); 990 __ j(above, &non_proxy);
1020 __ mov(ebx, Immediate(Smi::FromInt(0))); // Zero indicates proxy 991 __ mov(ebx, Immediate(Smi::FromInt(0))); // Zero indicates proxy
1021 __ bind(&non_proxy); 992 __ bind(&non_proxy);
1022 __ push(ebx); // Smi 993 __ push(ebx); // Smi
1023 __ push(eax); // Array 994 __ push(eax); // Array
1024 __ mov(eax, FieldOperand(eax, FixedArray::kLengthOffset)); 995 __ mov(eax, FieldOperand(eax, FixedArray::kLengthOffset));
1025 __ push(eax); // Fixed array length (as smi). 996 __ push(eax); // Fixed array length (as smi).
1026 __ push(Immediate(Smi::FromInt(0))); // Initial index. 997 __ push(Immediate(Smi::FromInt(0))); // Initial index.
1027 998
1028 // 1 ~ The object has already been pushed.
1029 increment_stack_height(ForIn::kElementCount - 1);
1030 // Generate code for doing the condition check. 999 // Generate code for doing the condition check.
1031 __ bind(&loop); 1000 __ bind(&loop);
1032 __ mov(eax, Operand(esp, 0 * kPointerSize)); // Get the current index. 1001 __ mov(eax, Operand(esp, 0 * kPointerSize)); // Get the current index.
1033 __ cmp(eax, Operand(esp, 1 * kPointerSize)); // Compare to the array length. 1002 __ cmp(eax, Operand(esp, 1 * kPointerSize)); // Compare to the array length.
1034 __ j(above_equal, loop_statement.break_label()); 1003 __ j(above_equal, loop_statement.break_label());
1035 1004
1036 // Get the current entry of the array into register ebx. 1005 // Get the current entry of the array into register ebx.
1037 __ mov(ebx, Operand(esp, 2 * kPointerSize)); 1006 __ mov(ebx, Operand(esp, 2 * kPointerSize));
1038 __ mov(ebx, FieldOperand(ebx, eax, times_2, FixedArray::kHeaderSize)); 1007 __ mov(ebx, FieldOperand(ebx, eax, times_2, FixedArray::kHeaderSize));
1039 1008
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1081 __ bind(loop_statement.continue_label()); 1050 __ bind(loop_statement.continue_label());
1082 __ add(Operand(esp, 0 * kPointerSize), Immediate(Smi::FromInt(1))); 1051 __ add(Operand(esp, 0 * kPointerSize), Immediate(Smi::FromInt(1)));
1083 1052
1084 EmitStackCheck(stmt); 1053 EmitStackCheck(stmt);
1085 __ jmp(&loop); 1054 __ jmp(&loop);
1086 1055
1087 // Remove the pointers stored on the stack. 1056 // Remove the pointers stored on the stack.
1088 __ bind(loop_statement.break_label()); 1057 __ bind(loop_statement.break_label());
1089 __ add(esp, Immediate(5 * kPointerSize)); 1058 __ add(esp, Immediate(5 * kPointerSize));
1090 1059
1091 decrement_stack_height(ForIn::kElementCount);
1092 // Exit and decrement the loop depth. 1060 // Exit and decrement the loop depth.
1093 __ bind(&exit); 1061 __ bind(&exit);
1094 decrement_loop_depth(); 1062 decrement_loop_depth();
1095 } 1063 }
1096 1064
1097 1065
1098 void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info, 1066 void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info,
1099 bool pretenure) { 1067 bool pretenure) {
1100 // Use the fast case closure allocation code that allocates in new 1068 // Use the fast case closure allocation code that allocates in new
1101 // space for nested functions that don't need literals cloning. If 1069 // space for nested functions that don't need literals cloning. If
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after
1403 1371
1404 for (int i = 0; i < expr->properties()->length(); i++) { 1372 for (int i = 0; i < expr->properties()->length(); i++) {
1405 ObjectLiteral::Property* property = expr->properties()->at(i); 1373 ObjectLiteral::Property* property = expr->properties()->at(i);
1406 if (property->IsCompileTimeValue()) continue; 1374 if (property->IsCompileTimeValue()) continue;
1407 1375
1408 Literal* key = property->key(); 1376 Literal* key = property->key();
1409 Expression* value = property->value(); 1377 Expression* value = property->value();
1410 if (!result_saved) { 1378 if (!result_saved) {
1411 __ push(eax); // Save result on the stack 1379 __ push(eax); // Save result on the stack
1412 result_saved = true; 1380 result_saved = true;
1413 increment_stack_height();
1414 } 1381 }
1415 switch (property->kind()) { 1382 switch (property->kind()) {
1416 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1383 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1417 ASSERT(!CompileTimeValue::IsCompileTimeValue(value)); 1384 ASSERT(!CompileTimeValue::IsCompileTimeValue(value));
1418 // Fall through. 1385 // Fall through.
1419 case ObjectLiteral::Property::COMPUTED: 1386 case ObjectLiteral::Property::COMPUTED:
1420 if (key->handle()->IsSymbol()) { 1387 if (key->handle()->IsSymbol()) {
1421 if (property->emit_store()) { 1388 if (property->emit_store()) {
1422 VisitForAccumulatorValue(value); 1389 VisitForAccumulatorValue(value);
1423 __ mov(ecx, Immediate(key->handle())); 1390 __ mov(ecx, Immediate(key->handle()));
1424 __ mov(edx, Operand(esp, 0)); 1391 __ mov(edx, Operand(esp, 0));
1425 Handle<Code> ic = is_strict_mode() 1392 Handle<Code> ic = is_strict_mode()
1426 ? isolate()->builtins()->StoreIC_Initialize_Strict() 1393 ? isolate()->builtins()->StoreIC_Initialize_Strict()
1427 : isolate()->builtins()->StoreIC_Initialize(); 1394 : isolate()->builtins()->StoreIC_Initialize();
1428 __ call(ic, RelocInfo::CODE_TARGET, key->id()); 1395 __ call(ic, RelocInfo::CODE_TARGET, key->id());
1429 PrepareForBailoutForId(key->id(), NO_REGISTERS); 1396 PrepareForBailoutForId(key->id(), NO_REGISTERS);
1430 } else { 1397 } else {
1431 VisitForEffect(value); 1398 VisitForEffect(value);
1432 } 1399 }
1433 break; 1400 break;
1434 } 1401 }
1435 // Fall through. 1402 // Fall through.
1436 case ObjectLiteral::Property::PROTOTYPE: 1403 case ObjectLiteral::Property::PROTOTYPE:
1437 __ push(Operand(esp, 0)); // Duplicate receiver. 1404 __ push(Operand(esp, 0)); // Duplicate receiver.
1438 increment_stack_height();
1439 VisitForStackValue(key); 1405 VisitForStackValue(key);
1440 VisitForStackValue(value); 1406 VisitForStackValue(value);
1441 if (property->emit_store()) { 1407 if (property->emit_store()) {
1442 __ push(Immediate(Smi::FromInt(NONE))); // PropertyAttributes 1408 __ push(Immediate(Smi::FromInt(NONE))); // PropertyAttributes
1443 __ CallRuntime(Runtime::kSetProperty, 4); 1409 __ CallRuntime(Runtime::kSetProperty, 4);
1444 } else { 1410 } else {
1445 __ Drop(3); 1411 __ Drop(3);
1446 } 1412 }
1447 decrement_stack_height(3);
1448 break; 1413 break;
1449 case ObjectLiteral::Property::SETTER: 1414 case ObjectLiteral::Property::SETTER:
1450 case ObjectLiteral::Property::GETTER: 1415 case ObjectLiteral::Property::GETTER:
1451 __ push(Operand(esp, 0)); // Duplicate receiver. 1416 __ push(Operand(esp, 0)); // Duplicate receiver.
1452 increment_stack_height();
1453 VisitForStackValue(key); 1417 VisitForStackValue(key);
1454 __ push(Immediate(property->kind() == ObjectLiteral::Property::SETTER ? 1418 __ push(Immediate(property->kind() == ObjectLiteral::Property::SETTER ?
1455 Smi::FromInt(1) : 1419 Smi::FromInt(1) :
1456 Smi::FromInt(0))); 1420 Smi::FromInt(0)));
1457 increment_stack_height();
1458 VisitForStackValue(value); 1421 VisitForStackValue(value);
1459 __ CallRuntime(Runtime::kDefineAccessor, 4); 1422 __ CallRuntime(Runtime::kDefineAccessor, 4);
1460 decrement_stack_height(4);
1461 break; 1423 break;
1462 default: UNREACHABLE(); 1424 default: UNREACHABLE();
1463 } 1425 }
1464 } 1426 }
1465 1427
1466 if (expr->has_function()) { 1428 if (expr->has_function()) {
1467 ASSERT(result_saved); 1429 ASSERT(result_saved);
1468 __ push(Operand(esp, 0)); 1430 __ push(Operand(esp, 0));
1469 __ CallRuntime(Runtime::kToFastProperties, 1); 1431 __ CallRuntime(Runtime::kToFastProperties, 1);
1470 } 1432 }
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1525 // If the subexpression is a literal or a simple materialized literal it 1487 // If the subexpression is a literal or a simple materialized literal it
1526 // is already set in the cloned array. 1488 // is already set in the cloned array.
1527 if (subexpr->AsLiteral() != NULL || 1489 if (subexpr->AsLiteral() != NULL ||
1528 CompileTimeValue::IsCompileTimeValue(subexpr)) { 1490 CompileTimeValue::IsCompileTimeValue(subexpr)) {
1529 continue; 1491 continue;
1530 } 1492 }
1531 1493
1532 if (!result_saved) { 1494 if (!result_saved) {
1533 __ push(eax); 1495 __ push(eax);
1534 result_saved = true; 1496 result_saved = true;
1535 increment_stack_height();
1536 } 1497 }
1537 VisitForAccumulatorValue(subexpr); 1498 VisitForAccumulatorValue(subexpr);
1538 1499
1539 // Store the subexpression value in the array's elements. 1500 // Store the subexpression value in the array's elements.
1540 __ mov(ebx, Operand(esp, 0)); // Copy of array literal. 1501 __ mov(ebx, Operand(esp, 0)); // Copy of array literal.
1541 __ mov(edi, FieldOperand(ebx, JSObject::kMapOffset)); 1502 __ mov(edi, FieldOperand(ebx, JSObject::kMapOffset));
1542 __ mov(ebx, FieldOperand(ebx, JSObject::kElementsOffset)); 1503 __ mov(ebx, FieldOperand(ebx, JSObject::kElementsOffset));
1543 int offset = FixedArray::kHeaderSize + (i * kPointerSize); 1504 int offset = FixedArray::kHeaderSize + (i * kPointerSize);
1544 1505
1545 Label element_done; 1506 Label element_done;
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1603 context()->Plug(eax); 1564 context()->Plug(eax);
1604 } 1565 }
1605 } 1566 }
1606 1567
1607 1568
1608 void FullCodeGenerator::VisitAssignment(Assignment* expr) { 1569 void FullCodeGenerator::VisitAssignment(Assignment* expr) {
1609 Comment cmnt(masm_, "[ Assignment"); 1570 Comment cmnt(masm_, "[ Assignment");
1610 // Invalid left-hand sides are rewritten to have a 'throw ReferenceError' 1571 // Invalid left-hand sides are rewritten to have a 'throw ReferenceError'
1611 // on the left-hand side. 1572 // on the left-hand side.
1612 if (!expr->target()->IsValidLeftHandSide()) { 1573 if (!expr->target()->IsValidLeftHandSide()) {
1613 ASSERT(expr->target()->AsThrow() != NULL); 1574 VisitForEffect(expr->target());
1614 VisitInCurrentContext(expr->target()); // Throw does not plug the context
1615 context()->Plug(eax);
1616 return; 1575 return;
1617 } 1576 }
1618 1577
1619 // Left-hand side can only be a property, a global or a (parameter or local) 1578 // Left-hand side can only be a property, a global or a (parameter or local)
1620 // slot. 1579 // slot.
1621 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; 1580 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
1622 LhsKind assign_type = VARIABLE; 1581 LhsKind assign_type = VARIABLE;
1623 Property* property = expr->target()->AsProperty(); 1582 Property* property = expr->target()->AsProperty();
1624 if (property != NULL) { 1583 if (property != NULL) {
1625 assign_type = (property->key()->IsPropertyName()) 1584 assign_type = (property->key()->IsPropertyName())
1626 ? NAMED_PROPERTY 1585 ? NAMED_PROPERTY
1627 : KEYED_PROPERTY; 1586 : KEYED_PROPERTY;
1628 } 1587 }
1629 1588
1630 // Evaluate LHS expression. 1589 // Evaluate LHS expression.
1631 switch (assign_type) { 1590 switch (assign_type) {
1632 case VARIABLE: 1591 case VARIABLE:
1633 // Nothing to do here. 1592 // Nothing to do here.
1634 break; 1593 break;
1635 case NAMED_PROPERTY: 1594 case NAMED_PROPERTY:
1636 if (expr->is_compound()) { 1595 if (expr->is_compound()) {
1637 // We need the receiver both on the stack and in the accumulator. 1596 // We need the receiver both on the stack and in the accumulator.
1638 VisitForAccumulatorValue(property->obj()); 1597 VisitForAccumulatorValue(property->obj());
1639 __ push(result_register()); 1598 __ push(result_register());
1640 increment_stack_height();
1641 } else { 1599 } else {
1642 VisitForStackValue(property->obj()); 1600 VisitForStackValue(property->obj());
1643 } 1601 }
1644 break; 1602 break;
1645 case KEYED_PROPERTY: { 1603 case KEYED_PROPERTY: {
1646 if (expr->is_compound()) { 1604 if (expr->is_compound()) {
1647 VisitForStackValue(property->obj()); 1605 VisitForStackValue(property->obj());
1648 VisitForAccumulatorValue(property->key()); 1606 VisitForAccumulatorValue(property->key());
1649 __ mov(edx, Operand(esp, 0)); 1607 __ mov(edx, Operand(esp, 0));
1650 __ push(eax); 1608 __ push(eax);
1651 increment_stack_height();
1652 } else { 1609 } else {
1653 VisitForStackValue(property->obj()); 1610 VisitForStackValue(property->obj());
1654 VisitForStackValue(property->key()); 1611 VisitForStackValue(property->key());
1655 } 1612 }
1656 break; 1613 break;
1657 } 1614 }
1658 } 1615 }
1659 1616
1660 // For compound assignments we need another deoptimization point after the 1617 // For compound assignments we need another deoptimization point after the
1661 // variable/property load. 1618 // variable/property load.
(...skipping 11 matching lines...) Expand all
1673 break; 1630 break;
1674 case KEYED_PROPERTY: 1631 case KEYED_PROPERTY:
1675 EmitKeyedPropertyLoad(property); 1632 EmitKeyedPropertyLoad(property);
1676 PrepareForBailoutForId(expr->CompoundLoadId(), TOS_REG); 1633 PrepareForBailoutForId(expr->CompoundLoadId(), TOS_REG);
1677 break; 1634 break;
1678 } 1635 }
1679 } 1636 }
1680 1637
1681 Token::Value op = expr->binary_op(); 1638 Token::Value op = expr->binary_op();
1682 __ push(eax); // Left operand goes on the stack. 1639 __ push(eax); // Left operand goes on the stack.
1683 increment_stack_height();
1684 VisitForAccumulatorValue(expr->value()); 1640 VisitForAccumulatorValue(expr->value());
1685 1641
1686 OverwriteMode mode = expr->value()->ResultOverwriteAllowed() 1642 OverwriteMode mode = expr->value()->ResultOverwriteAllowed()
1687 ? OVERWRITE_RIGHT 1643 ? OVERWRITE_RIGHT
1688 : NO_OVERWRITE; 1644 : NO_OVERWRITE;
1689 SetSourcePosition(expr->position() + 1); 1645 SetSourcePosition(expr->position() + 1);
1690 if (ShouldInlineSmiCase(op)) { 1646 if (ShouldInlineSmiCase(op)) {
1691 EmitInlineSmiBinaryOp(expr->binary_operation(), 1647 EmitInlineSmiBinaryOp(expr->binary_operation(),
1692 op, 1648 op,
1693 mode, 1649 mode,
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1743 1699
1744 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, 1700 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
1745 Token::Value op, 1701 Token::Value op,
1746 OverwriteMode mode, 1702 OverwriteMode mode,
1747 Expression* left, 1703 Expression* left,
1748 Expression* right) { 1704 Expression* right) {
1749 // Do combined smi check of the operands. Left operand is on the 1705 // Do combined smi check of the operands. Left operand is on the
1750 // stack. Right operand is in eax. 1706 // stack. Right operand is in eax.
1751 Label smi_case, done, stub_call; 1707 Label smi_case, done, stub_call;
1752 __ pop(edx); 1708 __ pop(edx);
1753 decrement_stack_height();
1754 __ mov(ecx, eax); 1709 __ mov(ecx, eax);
1755 __ or_(eax, edx); 1710 __ or_(eax, edx);
1756 JumpPatchSite patch_site(masm_); 1711 JumpPatchSite patch_site(masm_);
1757 patch_site.EmitJumpIfSmi(eax, &smi_case, Label::kNear); 1712 patch_site.EmitJumpIfSmi(eax, &smi_case, Label::kNear);
1758 1713
1759 __ bind(&stub_call); 1714 __ bind(&stub_call);
1760 __ mov(eax, ecx); 1715 __ mov(eax, ecx);
1761 BinaryOpStub stub(op, mode); 1716 BinaryOpStub stub(op, mode);
1762 __ call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id()); 1717 __ call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id());
1763 patch_site.EmitPatchInfo(); 1718 patch_site.EmitPatchInfo();
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
1835 1790
1836 __ bind(&done); 1791 __ bind(&done);
1837 context()->Plug(eax); 1792 context()->Plug(eax);
1838 } 1793 }
1839 1794
1840 1795
1841 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, 1796 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr,
1842 Token::Value op, 1797 Token::Value op,
1843 OverwriteMode mode) { 1798 OverwriteMode mode) {
1844 __ pop(edx); 1799 __ pop(edx);
1845 decrement_stack_height();
1846 BinaryOpStub stub(op, mode); 1800 BinaryOpStub stub(op, mode);
1847 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. 1801 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
1848 __ call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id()); 1802 __ call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id());
1849 patch_site.EmitPatchInfo(); 1803 patch_site.EmitPatchInfo();
1850 context()->Plug(eax); 1804 context()->Plug(eax);
1851 } 1805 }
1852 1806
1853 1807
1854 void FullCodeGenerator::EmitAssignment(Expression* expr, int bailout_ast_id) { 1808 void FullCodeGenerator::EmitAssignment(Expression* expr, int bailout_ast_id) {
1855 // Invalid left-hand sides are rewritten to have a 'throw 1809 // Invalid left-hand sides are rewritten to have a 'throw
1856 // ReferenceError' on the left-hand side. 1810 // ReferenceError' on the left-hand side.
1857 if (!expr->IsValidLeftHandSide()) { 1811 if (!expr->IsValidLeftHandSide()) {
1858 ASSERT(expr->AsThrow() != NULL); 1812 VisitForEffect(expr);
1859 VisitInCurrentContext(expr); // Throw does not plug the context
1860 context()->Plug(eax);
1861 return; 1813 return;
1862 } 1814 }
1863 1815
1864 // Left-hand side can only be a property, a global or a (parameter or local) 1816 // Left-hand side can only be a property, a global or a (parameter or local)
1865 // slot. 1817 // slot.
1866 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; 1818 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
1867 LhsKind assign_type = VARIABLE; 1819 LhsKind assign_type = VARIABLE;
1868 Property* prop = expr->AsProperty(); 1820 Property* prop = expr->AsProperty();
1869 if (prop != NULL) { 1821 if (prop != NULL) {
1870 assign_type = (prop->key()->IsPropertyName()) 1822 assign_type = (prop->key()->IsPropertyName())
1871 ? NAMED_PROPERTY 1823 ? NAMED_PROPERTY
1872 : KEYED_PROPERTY; 1824 : KEYED_PROPERTY;
1873 } 1825 }
1874 1826
1875 switch (assign_type) { 1827 switch (assign_type) {
1876 case VARIABLE: { 1828 case VARIABLE: {
1877 Variable* var = expr->AsVariableProxy()->var(); 1829 Variable* var = expr->AsVariableProxy()->var();
1878 EffectContext context(this); 1830 EffectContext context(this);
1879 EmitVariableAssignment(var, Token::ASSIGN); 1831 EmitVariableAssignment(var, Token::ASSIGN);
1880 break; 1832 break;
1881 } 1833 }
1882 case NAMED_PROPERTY: { 1834 case NAMED_PROPERTY: {
1883 __ push(eax); // Preserve value. 1835 __ push(eax); // Preserve value.
1884 increment_stack_height();
1885 VisitForAccumulatorValue(prop->obj()); 1836 VisitForAccumulatorValue(prop->obj());
1886 __ mov(edx, eax); 1837 __ mov(edx, eax);
1887 __ pop(eax); // Restore value. 1838 __ pop(eax); // Restore value.
1888 decrement_stack_height();
1889 __ mov(ecx, prop->key()->AsLiteral()->handle()); 1839 __ mov(ecx, prop->key()->AsLiteral()->handle());
1890 Handle<Code> ic = is_strict_mode() 1840 Handle<Code> ic = is_strict_mode()
1891 ? isolate()->builtins()->StoreIC_Initialize_Strict() 1841 ? isolate()->builtins()->StoreIC_Initialize_Strict()
1892 : isolate()->builtins()->StoreIC_Initialize(); 1842 : isolate()->builtins()->StoreIC_Initialize();
1893 __ call(ic); 1843 __ call(ic);
1894 break; 1844 break;
1895 } 1845 }
1896 case KEYED_PROPERTY: { 1846 case KEYED_PROPERTY: {
1897 __ push(eax); // Preserve value. 1847 __ push(eax); // Preserve value.
1898 increment_stack_height();
1899 VisitForStackValue(prop->obj()); 1848 VisitForStackValue(prop->obj());
1900 VisitForAccumulatorValue(prop->key()); 1849 VisitForAccumulatorValue(prop->key());
1901 __ mov(ecx, eax); 1850 __ mov(ecx, eax);
1902 __ pop(edx); 1851 __ pop(edx);
1903 decrement_stack_height();
1904 __ pop(eax); // Restore value. 1852 __ pop(eax); // Restore value.
1905 decrement_stack_height();
1906 Handle<Code> ic = is_strict_mode() 1853 Handle<Code> ic = is_strict_mode()
1907 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 1854 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
1908 : isolate()->builtins()->KeyedStoreIC_Initialize(); 1855 : isolate()->builtins()->KeyedStoreIC_Initialize();
1909 __ call(ic); 1856 __ call(ic);
1910 break; 1857 break;
1911 } 1858 }
1912 } 1859 }
1913 PrepareForBailoutForId(bailout_ast_id, TOS_REG); 1860 PrepareForBailoutForId(bailout_ast_id, TOS_REG);
1914 context()->Plug(eax); 1861 context()->Plug(eax);
1915 } 1862 }
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
2022 __ pop(result_register()); 1969 __ pop(result_register());
2023 } 1970 }
2024 1971
2025 // Record source code position before IC call. 1972 // Record source code position before IC call.
2026 SetSourcePosition(expr->position()); 1973 SetSourcePosition(expr->position());
2027 __ mov(ecx, prop->key()->AsLiteral()->handle()); 1974 __ mov(ecx, prop->key()->AsLiteral()->handle());
2028 if (expr->ends_initialization_block()) { 1975 if (expr->ends_initialization_block()) {
2029 __ mov(edx, Operand(esp, 0)); 1976 __ mov(edx, Operand(esp, 0));
2030 } else { 1977 } else {
2031 __ pop(edx); 1978 __ pop(edx);
2032 decrement_stack_height();
2033 } 1979 }
2034 Handle<Code> ic = is_strict_mode() 1980 Handle<Code> ic = is_strict_mode()
2035 ? isolate()->builtins()->StoreIC_Initialize_Strict() 1981 ? isolate()->builtins()->StoreIC_Initialize_Strict()
2036 : isolate()->builtins()->StoreIC_Initialize(); 1982 : isolate()->builtins()->StoreIC_Initialize();
2037 __ call(ic, RelocInfo::CODE_TARGET, expr->id()); 1983 __ call(ic, RelocInfo::CODE_TARGET, expr->id());
2038 1984
2039 // If the assignment ends an initialization block, revert to fast case. 1985 // If the assignment ends an initialization block, revert to fast case.
2040 if (expr->ends_initialization_block()) { 1986 if (expr->ends_initialization_block()) {
2041 __ push(eax); // Result of assignment, saved even if not needed. 1987 __ push(eax); // Result of assignment, saved even if not needed.
2042 __ push(Operand(esp, kPointerSize)); // Receiver is under value. 1988 __ push(Operand(esp, kPointerSize)); // Receiver is under value.
2043 __ CallRuntime(Runtime::kToFastProperties, 1); 1989 __ CallRuntime(Runtime::kToFastProperties, 1);
2044 __ pop(eax); 1990 __ pop(eax);
2045 __ Drop(1); 1991 __ Drop(1);
2046 decrement_stack_height();
2047 } 1992 }
2048 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 1993 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2049 context()->Plug(eax); 1994 context()->Plug(eax);
2050 } 1995 }
2051 1996
2052 1997
2053 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { 1998 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
2054 // Assignment to a property, using a keyed store IC. 1999 // Assignment to a property, using a keyed store IC.
2055 2000
2056 // If the assignment starts a block of assignments to the same object, 2001 // If the assignment starts a block of assignments to the same object,
2057 // change to slow case to avoid the quadratic behavior of repeatedly 2002 // change to slow case to avoid the quadratic behavior of repeatedly
2058 // adding fast properties. 2003 // adding fast properties.
2059 if (expr->starts_initialization_block()) { 2004 if (expr->starts_initialization_block()) {
2060 __ push(result_register()); 2005 __ push(result_register());
2061 // Receiver is now under the key and value. 2006 // Receiver is now under the key and value.
2062 __ push(Operand(esp, 2 * kPointerSize)); 2007 __ push(Operand(esp, 2 * kPointerSize));
2063 __ CallRuntime(Runtime::kToSlowProperties, 1); 2008 __ CallRuntime(Runtime::kToSlowProperties, 1);
2064 __ pop(result_register()); 2009 __ pop(result_register());
2065 } 2010 }
2066 2011
2067 __ pop(ecx); 2012 __ pop(ecx);
2068 decrement_stack_height();
2069 if (expr->ends_initialization_block()) { 2013 if (expr->ends_initialization_block()) {
2070 __ mov(edx, Operand(esp, 0)); // Leave receiver on the stack for later. 2014 __ mov(edx, Operand(esp, 0)); // Leave receiver on the stack for later.
2071 } else { 2015 } else {
2072 __ pop(edx); 2016 __ pop(edx);
2073 decrement_stack_height();
2074 } 2017 }
2075 // Record source code position before IC call. 2018 // Record source code position before IC call.
2076 SetSourcePosition(expr->position()); 2019 SetSourcePosition(expr->position());
2077 Handle<Code> ic = is_strict_mode() 2020 Handle<Code> ic = is_strict_mode()
2078 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 2021 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
2079 : isolate()->builtins()->KeyedStoreIC_Initialize(); 2022 : isolate()->builtins()->KeyedStoreIC_Initialize();
2080 __ call(ic, RelocInfo::CODE_TARGET, expr->id()); 2023 __ call(ic, RelocInfo::CODE_TARGET, expr->id());
2081 2024
2082 // If the assignment ends an initialization block, revert to fast case. 2025 // If the assignment ends an initialization block, revert to fast case.
2083 if (expr->ends_initialization_block()) { 2026 if (expr->ends_initialization_block()) {
2084 __ pop(edx); 2027 __ pop(edx);
2085 __ push(eax); // Result of assignment, saved even if not needed. 2028 __ push(eax); // Result of assignment, saved even if not needed.
2086 __ push(edx); 2029 __ push(edx);
2087 __ CallRuntime(Runtime::kToFastProperties, 1); 2030 __ CallRuntime(Runtime::kToFastProperties, 1);
2088 __ pop(eax); 2031 __ pop(eax);
2089 decrement_stack_height();
2090 } 2032 }
2091 2033
2092 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2034 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2093 context()->Plug(eax); 2035 context()->Plug(eax);
2094 } 2036 }
2095 2037
2096 2038
2097 void FullCodeGenerator::VisitProperty(Property* expr) { 2039 void FullCodeGenerator::VisitProperty(Property* expr) {
2098 Comment cmnt(masm_, "[ Property"); 2040 Comment cmnt(masm_, "[ Property");
2099 Expression* key = expr->key(); 2041 Expression* key = expr->key();
2100 2042
2101 if (key->IsPropertyName()) { 2043 if (key->IsPropertyName()) {
2102 VisitForAccumulatorValue(expr->obj()); 2044 VisitForAccumulatorValue(expr->obj());
2103 EmitNamedPropertyLoad(expr); 2045 EmitNamedPropertyLoad(expr);
2104 context()->Plug(eax); 2046 context()->Plug(eax);
2105 } else { 2047 } else {
2106 VisitForStackValue(expr->obj()); 2048 VisitForStackValue(expr->obj());
2107 VisitForAccumulatorValue(expr->key()); 2049 VisitForAccumulatorValue(expr->key());
2108 __ pop(edx); 2050 __ pop(edx);
2109 decrement_stack_height();
2110 EmitKeyedPropertyLoad(expr); 2051 EmitKeyedPropertyLoad(expr);
2111 context()->Plug(eax); 2052 context()->Plug(eax);
2112 } 2053 }
2113 } 2054 }
2114 2055
2115 2056
2116 void FullCodeGenerator::EmitCallWithIC(Call* expr, 2057 void FullCodeGenerator::EmitCallWithIC(Call* expr,
2117 Handle<Object> name, 2058 Handle<Object> name,
2118 RelocInfo::Mode mode) { 2059 RelocInfo::Mode mode) {
2119 // Code common for calls using the IC. 2060 // Code common for calls using the IC.
2120 ZoneList<Expression*>* args = expr->arguments(); 2061 ZoneList<Expression*>* args = expr->arguments();
2121 int arg_count = args->length(); 2062 int arg_count = args->length();
2122 { PreservePositionScope scope(masm()->positions_recorder()); 2063 { PreservePositionScope scope(masm()->positions_recorder());
2123 for (int i = 0; i < arg_count; i++) { 2064 for (int i = 0; i < arg_count; i++) {
2124 VisitForStackValue(args->at(i)); 2065 VisitForStackValue(args->at(i));
2125 } 2066 }
2126 __ Set(ecx, Immediate(name)); 2067 __ Set(ecx, Immediate(name));
2127 } 2068 }
2128 // Record source position of the IC call. 2069 // Record source position of the IC call.
2129 SetSourcePosition(expr->position()); 2070 SetSourcePosition(expr->position());
2130 Handle<Code> ic = 2071 Handle<Code> ic =
2131 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); 2072 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode);
2132 __ call(ic, mode, expr->id()); 2073 __ call(ic, mode, expr->id());
2133 RecordJSReturnSite(expr); 2074 RecordJSReturnSite(expr);
2134 // Restore context register. 2075 // Restore context register.
2135 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2076 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2136 decrement_stack_height(arg_count + 1);
2137 context()->Plug(eax); 2077 context()->Plug(eax);
2138 } 2078 }
2139 2079
2140 2080
2141 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, 2081 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr,
2142 Expression* key) { 2082 Expression* key) {
2143 // Load the key. 2083 // Load the key.
2144 VisitForAccumulatorValue(key); 2084 VisitForAccumulatorValue(key);
2145 2085
2146 // Swap the name of the function and the receiver on the stack to follow 2086 // Swap the name of the function and the receiver on the stack to follow
2147 // the calling convention for call ICs. 2087 // the calling convention for call ICs.
2148 __ pop(ecx); 2088 __ pop(ecx);
2149 __ push(eax); 2089 __ push(eax);
2150 __ push(ecx); 2090 __ push(ecx);
2151 increment_stack_height();
2152 2091
2153 // Load the arguments. 2092 // Load the arguments.
2154 ZoneList<Expression*>* args = expr->arguments(); 2093 ZoneList<Expression*>* args = expr->arguments();
2155 int arg_count = args->length(); 2094 int arg_count = args->length();
2156 { PreservePositionScope scope(masm()->positions_recorder()); 2095 { PreservePositionScope scope(masm()->positions_recorder());
2157 for (int i = 0; i < arg_count; i++) { 2096 for (int i = 0; i < arg_count; i++) {
2158 VisitForStackValue(args->at(i)); 2097 VisitForStackValue(args->at(i));
2159 } 2098 }
2160 } 2099 }
2161 // Record source position of the IC call. 2100 // Record source position of the IC call.
2162 SetSourcePosition(expr->position()); 2101 SetSourcePosition(expr->position());
2163 Handle<Code> ic = 2102 Handle<Code> ic =
2164 isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count); 2103 isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count);
2165 __ mov(ecx, Operand(esp, (arg_count + 1) * kPointerSize)); // Key. 2104 __ mov(ecx, Operand(esp, (arg_count + 1) * kPointerSize)); // Key.
2166 __ call(ic, RelocInfo::CODE_TARGET, expr->id()); 2105 __ call(ic, RelocInfo::CODE_TARGET, expr->id());
2167 RecordJSReturnSite(expr); 2106 RecordJSReturnSite(expr);
2168 // Restore context register. 2107 // Restore context register.
2169 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2108 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2170 decrement_stack_height(arg_count + 1);
2171 context()->DropAndPlug(1, eax); // Drop the key still on the stack. 2109 context()->DropAndPlug(1, eax); // Drop the key still on the stack.
2172 } 2110 }
2173 2111
2174 2112
2175 void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) { 2113 void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) {
2176 // Code common for calls using the call stub. 2114 // Code common for calls using the call stub.
2177 ZoneList<Expression*>* args = expr->arguments(); 2115 ZoneList<Expression*>* args = expr->arguments();
2178 int arg_count = args->length(); 2116 int arg_count = args->length();
2179 { PreservePositionScope scope(masm()->positions_recorder()); 2117 { PreservePositionScope scope(masm()->positions_recorder());
2180 for (int i = 0; i < arg_count; i++) { 2118 for (int i = 0; i < arg_count; i++) {
(...skipping 23 matching lines...) Expand all
2204 isolate()->factory()->NewJSGlobalPropertyCell(uninitialized); 2142 isolate()->factory()->NewJSGlobalPropertyCell(uninitialized);
2205 __ test(eax, Immediate(cell)); 2143 __ test(eax, Immediate(cell));
2206 // Patching code in the stub assumes the opcode is 1 byte and there is 2144 // Patching code in the stub assumes the opcode is 1 byte and there is
2207 // word for a pointer in the operand. 2145 // word for a pointer in the operand.
2208 ASSERT(masm()->pc_offset() - return_site_offset >= 1 + kPointerSize); 2146 ASSERT(masm()->pc_offset() - return_site_offset >= 1 + kPointerSize);
2209 } 2147 }
2210 2148
2211 RecordJSReturnSite(expr); 2149 RecordJSReturnSite(expr);
2212 // Restore context register. 2150 // Restore context register.
2213 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2151 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2214
2215 decrement_stack_height(arg_count + 1);
2216 context()->DropAndPlug(1, eax); 2152 context()->DropAndPlug(1, eax);
2217 } 2153 }
2218 2154
2219 2155
2220 void FullCodeGenerator::EmitResolvePossiblyDirectEval(ResolveEvalFlag flag, 2156 void FullCodeGenerator::EmitResolvePossiblyDirectEval(ResolveEvalFlag flag,
2221 int arg_count) { 2157 int arg_count) {
2222 // Push copy of the first argument or undefined if it doesn't exist. 2158 // Push copy of the first argument or undefined if it doesn't exist.
2223 if (arg_count > 0) { 2159 if (arg_count > 0) {
2224 __ push(Operand(esp, arg_count * kPointerSize)); 2160 __ push(Operand(esp, arg_count * kPointerSize));
2225 } else { 2161 } else {
(...skipping 30 matching lines...) Expand all
2256 if (proxy != NULL && proxy->var()->is_possibly_eval()) { 2192 if (proxy != NULL && proxy->var()->is_possibly_eval()) {
2257 // In a call to eval, we first call %ResolvePossiblyDirectEval to 2193 // In a call to eval, we first call %ResolvePossiblyDirectEval to
2258 // resolve the function we need to call and the receiver of the call. 2194 // resolve the function we need to call and the receiver of the call.
2259 // Then we call the resolved function using the given arguments. 2195 // Then we call the resolved function using the given arguments.
2260 ZoneList<Expression*>* args = expr->arguments(); 2196 ZoneList<Expression*>* args = expr->arguments();
2261 int arg_count = args->length(); 2197 int arg_count = args->length();
2262 { PreservePositionScope pos_scope(masm()->positions_recorder()); 2198 { PreservePositionScope pos_scope(masm()->positions_recorder());
2263 VisitForStackValue(callee); 2199 VisitForStackValue(callee);
2264 // Reserved receiver slot. 2200 // Reserved receiver slot.
2265 __ push(Immediate(isolate()->factory()->undefined_value())); 2201 __ push(Immediate(isolate()->factory()->undefined_value()));
2266 increment_stack_height(); 2202
2267 // Push the arguments. 2203 // Push the arguments.
2268 for (int i = 0; i < arg_count; i++) { 2204 for (int i = 0; i < arg_count; i++) {
2269 VisitForStackValue(args->at(i)); 2205 VisitForStackValue(args->at(i));
2270 } 2206 }
2271 2207
2272 // If we know that eval can only be shadowed by eval-introduced 2208 // If we know that eval can only be shadowed by eval-introduced
2273 // variables we attempt to load the global eval function directly in 2209 // variables we attempt to load the global eval function directly in
2274 // generated code. If we succeed, there is no need to perform a 2210 // generated code. If we succeed, there is no need to perform a
2275 // context lookup in the runtime system. 2211 // context lookup in the runtime system.
2276 Label done; 2212 Label done;
(...skipping 19 matching lines...) Expand all
2296 __ mov(Operand(esp, (arg_count + 0) * kPointerSize), edx); 2232 __ mov(Operand(esp, (arg_count + 0) * kPointerSize), edx);
2297 __ mov(Operand(esp, (arg_count + 1) * kPointerSize), eax); 2233 __ mov(Operand(esp, (arg_count + 1) * kPointerSize), eax);
2298 } 2234 }
2299 // Record source position for debugger. 2235 // Record source position for debugger.
2300 SetSourcePosition(expr->position()); 2236 SetSourcePosition(expr->position());
2301 CallFunctionStub stub(arg_count, RECEIVER_MIGHT_BE_IMPLICIT); 2237 CallFunctionStub stub(arg_count, RECEIVER_MIGHT_BE_IMPLICIT);
2302 __ CallStub(&stub); 2238 __ CallStub(&stub);
2303 RecordJSReturnSite(expr); 2239 RecordJSReturnSite(expr);
2304 // Restore context register. 2240 // Restore context register.
2305 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2241 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2306 decrement_stack_height(arg_count + 1); // Function is left on the stack.
2307 context()->DropAndPlug(1, eax); 2242 context()->DropAndPlug(1, eax);
2308 2243
2309 } else if (proxy != NULL && proxy->var()->IsUnallocated()) { 2244 } else if (proxy != NULL && proxy->var()->IsUnallocated()) {
2310 // Push global object as receiver for the call IC. 2245 // Push global object as receiver for the call IC.
2311 __ push(GlobalObjectOperand()); 2246 __ push(GlobalObjectOperand());
2312 increment_stack_height();
2313 EmitCallWithIC(expr, proxy->name(), RelocInfo::CODE_TARGET_CONTEXT); 2247 EmitCallWithIC(expr, proxy->name(), RelocInfo::CODE_TARGET_CONTEXT);
2314 2248
2315 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { 2249 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) {
2316 // Call to a lookup slot (dynamically introduced variable). 2250 // Call to a lookup slot (dynamically introduced variable).
2317 Label slow, done; 2251 Label slow, done;
2318 { PreservePositionScope scope(masm()->positions_recorder()); 2252 { PreservePositionScope scope(masm()->positions_recorder());
2319 // Generate code for loading from variables potentially shadowed by 2253 // Generate code for loading from variables potentially shadowed by
2320 // eval-introduced variables. 2254 // eval-introduced variables.
2321 EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done); 2255 EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done);
2322 } 2256 }
2323 __ bind(&slow); 2257 __ bind(&slow);
2324 // Call the runtime to find the function to call (returned in eax) and 2258 // Call the runtime to find the function to call (returned in eax) and
2325 // the object holding it (returned in edx). 2259 // the object holding it (returned in edx).
2326 __ push(context_register()); 2260 __ push(context_register());
2327 __ push(Immediate(proxy->name())); 2261 __ push(Immediate(proxy->name()));
2328 __ CallRuntime(Runtime::kLoadContextSlot, 2); 2262 __ CallRuntime(Runtime::kLoadContextSlot, 2);
2329 __ push(eax); // Function. 2263 __ push(eax); // Function.
2330 __ push(edx); // Receiver. 2264 __ push(edx); // Receiver.
2331 increment_stack_height(2);
2332 2265
2333 // If fast case code has been generated, emit code to push the function 2266 // If fast case code has been generated, emit code to push the function
2334 // and receiver and have the slow path jump around this code. 2267 // and receiver and have the slow path jump around this code.
2335 if (done.is_linked()) { 2268 if (done.is_linked()) {
2336 Label call; 2269 Label call;
2337 __ jmp(&call, Label::kNear); 2270 __ jmp(&call, Label::kNear);
2338 __ bind(&done); 2271 __ bind(&done);
2339 // Push function. Stack height already incremented in slow case 2272 // Push function.
2340 // above.
2341 __ push(eax); 2273 __ push(eax);
2342 // The receiver is implicitly the global receiver. Indicate this by 2274 // The receiver is implicitly the global receiver. Indicate this by
2343 // passing the hole to the call function stub. 2275 // passing the hole to the call function stub.
2344 __ push(Immediate(isolate()->factory()->the_hole_value())); 2276 __ push(Immediate(isolate()->factory()->the_hole_value()));
2345 __ bind(&call); 2277 __ bind(&call);
2346 } 2278 }
2347 2279
2348 // The receiver is either the global receiver or an object found by 2280 // The receiver is either the global receiver or an object found by
2349 // LoadContextSlot. That object could be the hole if the receiver is 2281 // LoadContextSlot. That object could be the hole if the receiver is
2350 // implicitly the global object. 2282 // implicitly the global object.
(...skipping 12 matching lines...) Expand all
2363 } 2295 }
2364 2296
2365 } else { 2297 } else {
2366 // Call to an arbitrary expression not handled specially above. 2298 // Call to an arbitrary expression not handled specially above.
2367 { PreservePositionScope scope(masm()->positions_recorder()); 2299 { PreservePositionScope scope(masm()->positions_recorder());
2368 VisitForStackValue(callee); 2300 VisitForStackValue(callee);
2369 } 2301 }
2370 // Load global receiver object. 2302 // Load global receiver object.
2371 __ mov(ebx, GlobalObjectOperand()); 2303 __ mov(ebx, GlobalObjectOperand());
2372 __ push(FieldOperand(ebx, GlobalObject::kGlobalReceiverOffset)); 2304 __ push(FieldOperand(ebx, GlobalObject::kGlobalReceiverOffset));
2373 increment_stack_height();
2374 // Emit function call. 2305 // Emit function call.
2375 EmitCallWithStub(expr, NO_CALL_FUNCTION_FLAGS); 2306 EmitCallWithStub(expr, NO_CALL_FUNCTION_FLAGS);
2376 } 2307 }
2377 2308
2378 #ifdef DEBUG 2309 #ifdef DEBUG
2379 // RecordJSReturnSite should have been called. 2310 // RecordJSReturnSite should have been called.
2380 ASSERT(expr->return_is_recorded_); 2311 ASSERT(expr->return_is_recorded_);
2381 #endif 2312 #endif
2382 } 2313 }
2383 2314
(...skipping 20 matching lines...) Expand all
2404 // constructor invocation. 2335 // constructor invocation.
2405 SetSourcePosition(expr->position()); 2336 SetSourcePosition(expr->position());
2406 2337
2407 // Load function and argument count into edi and eax. 2338 // Load function and argument count into edi and eax.
2408 __ SafeSet(eax, Immediate(arg_count)); 2339 __ SafeSet(eax, Immediate(arg_count));
2409 __ mov(edi, Operand(esp, arg_count * kPointerSize)); 2340 __ mov(edi, Operand(esp, arg_count * kPointerSize));
2410 2341
2411 Handle<Code> construct_builtin = 2342 Handle<Code> construct_builtin =
2412 isolate()->builtins()->JSConstructCall(); 2343 isolate()->builtins()->JSConstructCall();
2413 __ call(construct_builtin, RelocInfo::CONSTRUCT_CALL); 2344 __ call(construct_builtin, RelocInfo::CONSTRUCT_CALL);
2414
2415 decrement_stack_height(arg_count + 1);
2416 context()->Plug(eax); 2345 context()->Plug(eax);
2417 } 2346 }
2418 2347
2419 2348
2420 void FullCodeGenerator::EmitIsSmi(ZoneList<Expression*>* args) { 2349 void FullCodeGenerator::EmitIsSmi(ZoneList<Expression*>* args) {
2421 ASSERT(args->length() == 1); 2350 ASSERT(args->length() == 1);
2422 2351
2423 VisitForAccumulatorValue(args->at(0)); 2352 VisitForAccumulatorValue(args->at(0));
2424 2353
2425 Label materialize_true, materialize_false; 2354 Label materialize_true, materialize_false;
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after
2718 VisitForAccumulatorValue(args->at(1)); 2647 VisitForAccumulatorValue(args->at(1));
2719 2648
2720 Label materialize_true, materialize_false; 2649 Label materialize_true, materialize_false;
2721 Label* if_true = NULL; 2650 Label* if_true = NULL;
2722 Label* if_false = NULL; 2651 Label* if_false = NULL;
2723 Label* fall_through = NULL; 2652 Label* fall_through = NULL;
2724 context()->PrepareTest(&materialize_true, &materialize_false, 2653 context()->PrepareTest(&materialize_true, &materialize_false,
2725 &if_true, &if_false, &fall_through); 2654 &if_true, &if_false, &fall_through);
2726 2655
2727 __ pop(ebx); 2656 __ pop(ebx);
2728 decrement_stack_height();
2729 __ cmp(eax, ebx); 2657 __ cmp(eax, ebx);
2730 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); 2658 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
2731 Split(equal, if_true, if_false, fall_through); 2659 Split(equal, if_true, if_false, fall_through);
2732 2660
2733 context()->Plug(if_true, if_false); 2661 context()->Plug(if_true, if_false);
2734 } 2662 }
2735 2663
2736 2664
2737 void FullCodeGenerator::EmitArguments(ZoneList<Expression*>* args) { 2665 void FullCodeGenerator::EmitArguments(ZoneList<Expression*>* args) {
2738 ASSERT(args->length() == 1); 2666 ASSERT(args->length() == 1);
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
2837 // 0 (literal string): The type of logging (corresponds to the flags). 2765 // 0 (literal string): The type of logging (corresponds to the flags).
2838 // This is used to determine whether or not to generate the log call. 2766 // This is used to determine whether or not to generate the log call.
2839 // 1 (string): Format string. Access the string at argument index 2 2767 // 1 (string): Format string. Access the string at argument index 2
2840 // with '%2s' (see Logger::LogRuntime for all the formats). 2768 // with '%2s' (see Logger::LogRuntime for all the formats).
2841 // 2 (array): Arguments to the format string. 2769 // 2 (array): Arguments to the format string.
2842 ASSERT_EQ(args->length(), 3); 2770 ASSERT_EQ(args->length(), 3);
2843 if (CodeGenerator::ShouldGenerateLog(args->at(0))) { 2771 if (CodeGenerator::ShouldGenerateLog(args->at(0))) {
2844 VisitForStackValue(args->at(1)); 2772 VisitForStackValue(args->at(1));
2845 VisitForStackValue(args->at(2)); 2773 VisitForStackValue(args->at(2));
2846 __ CallRuntime(Runtime::kLog, 2); 2774 __ CallRuntime(Runtime::kLog, 2);
2847 decrement_stack_height(2);
2848 } 2775 }
2849 // Finally, we're expected to leave a value on the top of the stack. 2776 // Finally, we're expected to leave a value on the top of the stack.
2850 __ mov(eax, isolate()->factory()->undefined_value()); 2777 __ mov(eax, isolate()->factory()->undefined_value());
2851 context()->Plug(eax); 2778 context()->Plug(eax);
2852 } 2779 }
2853 2780
2854 2781
2855 void FullCodeGenerator::EmitRandomHeapNumber(ZoneList<Expression*>* args) { 2782 void FullCodeGenerator::EmitRandomHeapNumber(ZoneList<Expression*>* args) {
2856 ASSERT(args->length() == 0); 2783 ASSERT(args->length() == 0);
2857 2784
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
2904 2831
2905 2832
2906 void FullCodeGenerator::EmitSubString(ZoneList<Expression*>* args) { 2833 void FullCodeGenerator::EmitSubString(ZoneList<Expression*>* args) {
2907 // Load the arguments on the stack and call the stub. 2834 // Load the arguments on the stack and call the stub.
2908 SubStringStub stub; 2835 SubStringStub stub;
2909 ASSERT(args->length() == 3); 2836 ASSERT(args->length() == 3);
2910 VisitForStackValue(args->at(0)); 2837 VisitForStackValue(args->at(0));
2911 VisitForStackValue(args->at(1)); 2838 VisitForStackValue(args->at(1));
2912 VisitForStackValue(args->at(2)); 2839 VisitForStackValue(args->at(2));
2913 __ CallStub(&stub); 2840 __ CallStub(&stub);
2914 decrement_stack_height(3);
2915 context()->Plug(eax); 2841 context()->Plug(eax);
2916 } 2842 }
2917 2843
2918 2844
2919 void FullCodeGenerator::EmitRegExpExec(ZoneList<Expression*>* args) { 2845 void FullCodeGenerator::EmitRegExpExec(ZoneList<Expression*>* args) {
2920 // Load the arguments on the stack and call the stub. 2846 // Load the arguments on the stack and call the stub.
2921 RegExpExecStub stub; 2847 RegExpExecStub stub;
2922 ASSERT(args->length() == 4); 2848 ASSERT(args->length() == 4);
2923 VisitForStackValue(args->at(0)); 2849 VisitForStackValue(args->at(0));
2924 VisitForStackValue(args->at(1)); 2850 VisitForStackValue(args->at(1));
2925 VisitForStackValue(args->at(2)); 2851 VisitForStackValue(args->at(2));
2926 VisitForStackValue(args->at(3)); 2852 VisitForStackValue(args->at(3));
2927 __ CallStub(&stub); 2853 __ CallStub(&stub);
2928 decrement_stack_height(4);
2929 context()->Plug(eax); 2854 context()->Plug(eax);
2930 } 2855 }
2931 2856
2932 2857
2933 void FullCodeGenerator::EmitValueOf(ZoneList<Expression*>* args) { 2858 void FullCodeGenerator::EmitValueOf(ZoneList<Expression*>* args) {
2934 ASSERT(args->length() == 1); 2859 ASSERT(args->length() == 1);
2935 2860
2936 VisitForAccumulatorValue(args->at(0)); // Load the object. 2861 VisitForAccumulatorValue(args->at(0)); // Load the object.
2937 2862
2938 Label done; 2863 Label done;
(...skipping 14 matching lines...) Expand all
2953 ASSERT(args->length() == 2); 2878 ASSERT(args->length() == 2);
2954 VisitForStackValue(args->at(0)); 2879 VisitForStackValue(args->at(0));
2955 VisitForStackValue(args->at(1)); 2880 VisitForStackValue(args->at(1));
2956 2881
2957 if (CpuFeatures::IsSupported(SSE2)) { 2882 if (CpuFeatures::IsSupported(SSE2)) {
2958 MathPowStub stub; 2883 MathPowStub stub;
2959 __ CallStub(&stub); 2884 __ CallStub(&stub);
2960 } else { 2885 } else {
2961 __ CallRuntime(Runtime::kMath_pow, 2); 2886 __ CallRuntime(Runtime::kMath_pow, 2);
2962 } 2887 }
2963 decrement_stack_height(2);
2964 context()->Plug(eax); 2888 context()->Plug(eax);
2965 } 2889 }
2966 2890
2967 2891
2968 void FullCodeGenerator::EmitSetValueOf(ZoneList<Expression*>* args) { 2892 void FullCodeGenerator::EmitSetValueOf(ZoneList<Expression*>* args) {
2969 ASSERT(args->length() == 2); 2893 ASSERT(args->length() == 2);
2970 2894
2971 VisitForStackValue(args->at(0)); // Load the object. 2895 VisitForStackValue(args->at(0)); // Load the object.
2972 VisitForAccumulatorValue(args->at(1)); // Load the value. 2896 VisitForAccumulatorValue(args->at(1)); // Load the value.
2973 __ pop(ebx); // eax = value. ebx = object. 2897 __ pop(ebx); // eax = value. ebx = object.
2974 decrement_stack_height();
2975 2898
2976 Label done; 2899 Label done;
2977 // If the object is a smi, return the value. 2900 // If the object is a smi, return the value.
2978 __ JumpIfSmi(ebx, &done, Label::kNear); 2901 __ JumpIfSmi(ebx, &done, Label::kNear);
2979 2902
2980 // If the object is not a value type, return the value. 2903 // If the object is not a value type, return the value.
2981 __ CmpObjectType(ebx, JS_VALUE_TYPE, ecx); 2904 __ CmpObjectType(ebx, JS_VALUE_TYPE, ecx);
2982 __ j(not_equal, &done, Label::kNear); 2905 __ j(not_equal, &done, Label::kNear);
2983 2906
2984 // Store the value. 2907 // Store the value.
(...skipping 10 matching lines...) Expand all
2995 2918
2996 2919
2997 void FullCodeGenerator::EmitNumberToString(ZoneList<Expression*>* args) { 2920 void FullCodeGenerator::EmitNumberToString(ZoneList<Expression*>* args) {
2998 ASSERT_EQ(args->length(), 1); 2921 ASSERT_EQ(args->length(), 1);
2999 2922
3000 // Load the argument on the stack and call the stub. 2923 // Load the argument on the stack and call the stub.
3001 VisitForStackValue(args->at(0)); 2924 VisitForStackValue(args->at(0));
3002 2925
3003 NumberToStringStub stub; 2926 NumberToStringStub stub;
3004 __ CallStub(&stub); 2927 __ CallStub(&stub);
3005 decrement_stack_height();
3006 context()->Plug(eax); 2928 context()->Plug(eax);
3007 } 2929 }
3008 2930
3009 2931
3010 void FullCodeGenerator::EmitStringCharFromCode(ZoneList<Expression*>* args) { 2932 void FullCodeGenerator::EmitStringCharFromCode(ZoneList<Expression*>* args) {
3011 ASSERT(args->length() == 1); 2933 ASSERT(args->length() == 1);
3012 2934
3013 VisitForAccumulatorValue(args->at(0)); 2935 VisitForAccumulatorValue(args->at(0));
3014 2936
3015 Label done; 2937 Label done;
(...skipping 14 matching lines...) Expand all
3030 2952
3031 VisitForStackValue(args->at(0)); 2953 VisitForStackValue(args->at(0));
3032 VisitForAccumulatorValue(args->at(1)); 2954 VisitForAccumulatorValue(args->at(1));
3033 2955
3034 Register object = ebx; 2956 Register object = ebx;
3035 Register index = eax; 2957 Register index = eax;
3036 Register scratch = ecx; 2958 Register scratch = ecx;
3037 Register result = edx; 2959 Register result = edx;
3038 2960
3039 __ pop(object); 2961 __ pop(object);
3040 decrement_stack_height();
3041 2962
3042 Label need_conversion; 2963 Label need_conversion;
3043 Label index_out_of_range; 2964 Label index_out_of_range;
3044 Label done; 2965 Label done;
3045 StringCharCodeAtGenerator generator(object, 2966 StringCharCodeAtGenerator generator(object,
3046 index, 2967 index,
3047 scratch, 2968 scratch,
3048 result, 2969 result,
3049 &need_conversion, 2970 &need_conversion,
3050 &need_conversion, 2971 &need_conversion,
(...skipping 28 matching lines...) Expand all
3079 VisitForStackValue(args->at(0)); 3000 VisitForStackValue(args->at(0));
3080 VisitForAccumulatorValue(args->at(1)); 3001 VisitForAccumulatorValue(args->at(1));
3081 3002
3082 Register object = ebx; 3003 Register object = ebx;
3083 Register index = eax; 3004 Register index = eax;
3084 Register scratch1 = ecx; 3005 Register scratch1 = ecx;
3085 Register scratch2 = edx; 3006 Register scratch2 = edx;
3086 Register result = eax; 3007 Register result = eax;
3087 3008
3088 __ pop(object); 3009 __ pop(object);
3089 decrement_stack_height();
3090 3010
3091 Label need_conversion; 3011 Label need_conversion;
3092 Label index_out_of_range; 3012 Label index_out_of_range;
3093 Label done; 3013 Label done;
3094 StringCharAtGenerator generator(object, 3014 StringCharAtGenerator generator(object,
3095 index, 3015 index,
3096 scratch1, 3016 scratch1,
3097 scratch2, 3017 scratch2,
3098 result, 3018 result,
3099 &need_conversion, 3019 &need_conversion,
(...skipping 24 matching lines...) Expand all
3124 3044
3125 3045
3126 void FullCodeGenerator::EmitStringAdd(ZoneList<Expression*>* args) { 3046 void FullCodeGenerator::EmitStringAdd(ZoneList<Expression*>* args) {
3127 ASSERT_EQ(2, args->length()); 3047 ASSERT_EQ(2, args->length());
3128 3048
3129 VisitForStackValue(args->at(0)); 3049 VisitForStackValue(args->at(0));
3130 VisitForStackValue(args->at(1)); 3050 VisitForStackValue(args->at(1));
3131 3051
3132 StringAddStub stub(NO_STRING_ADD_FLAGS); 3052 StringAddStub stub(NO_STRING_ADD_FLAGS);
3133 __ CallStub(&stub); 3053 __ CallStub(&stub);
3134 decrement_stack_height(2);
3135 context()->Plug(eax); 3054 context()->Plug(eax);
3136 } 3055 }
3137 3056
3138 3057
3139 void FullCodeGenerator::EmitStringCompare(ZoneList<Expression*>* args) { 3058 void FullCodeGenerator::EmitStringCompare(ZoneList<Expression*>* args) {
3140 ASSERT_EQ(2, args->length()); 3059 ASSERT_EQ(2, args->length());
3141 3060
3142 VisitForStackValue(args->at(0)); 3061 VisitForStackValue(args->at(0));
3143 VisitForStackValue(args->at(1)); 3062 VisitForStackValue(args->at(1));
3144 3063
3145 StringCompareStub stub; 3064 StringCompareStub stub;
3146 __ CallStub(&stub); 3065 __ CallStub(&stub);
3147 decrement_stack_height(2);
3148 context()->Plug(eax); 3066 context()->Plug(eax);
3149 } 3067 }
3150 3068
3151 3069
3152 void FullCodeGenerator::EmitMathSin(ZoneList<Expression*>* args) { 3070 void FullCodeGenerator::EmitMathSin(ZoneList<Expression*>* args) {
3153 // Load the argument on the stack and call the stub. 3071 // Load the argument on the stack and call the stub.
3154 TranscendentalCacheStub stub(TranscendentalCache::SIN, 3072 TranscendentalCacheStub stub(TranscendentalCache::SIN,
3155 TranscendentalCacheStub::TAGGED); 3073 TranscendentalCacheStub::TAGGED);
3156 ASSERT(args->length() == 1); 3074 ASSERT(args->length() == 1);
3157 VisitForStackValue(args->at(0)); 3075 VisitForStackValue(args->at(0));
3158 __ CallStub(&stub); 3076 __ CallStub(&stub);
3159 decrement_stack_height();
3160 context()->Plug(eax); 3077 context()->Plug(eax);
3161 } 3078 }
3162 3079
3163 3080
3164 void FullCodeGenerator::EmitMathCos(ZoneList<Expression*>* args) { 3081 void FullCodeGenerator::EmitMathCos(ZoneList<Expression*>* args) {
3165 // Load the argument on the stack and call the stub. 3082 // Load the argument on the stack and call the stub.
3166 TranscendentalCacheStub stub(TranscendentalCache::COS, 3083 TranscendentalCacheStub stub(TranscendentalCache::COS,
3167 TranscendentalCacheStub::TAGGED); 3084 TranscendentalCacheStub::TAGGED);
3168 ASSERT(args->length() == 1); 3085 ASSERT(args->length() == 1);
3169 VisitForStackValue(args->at(0)); 3086 VisitForStackValue(args->at(0));
3170 __ CallStub(&stub); 3087 __ CallStub(&stub);
3171 decrement_stack_height();
3172 context()->Plug(eax); 3088 context()->Plug(eax);
3173 } 3089 }
3174 3090
3175 3091
3176 void FullCodeGenerator::EmitMathLog(ZoneList<Expression*>* args) { 3092 void FullCodeGenerator::EmitMathLog(ZoneList<Expression*>* args) {
3177 // Load the argument on the stack and call the stub. 3093 // Load the argument on the stack and call the stub.
3178 TranscendentalCacheStub stub(TranscendentalCache::LOG, 3094 TranscendentalCacheStub stub(TranscendentalCache::LOG,
3179 TranscendentalCacheStub::TAGGED); 3095 TranscendentalCacheStub::TAGGED);
3180 ASSERT(args->length() == 1); 3096 ASSERT(args->length() == 1);
3181 VisitForStackValue(args->at(0)); 3097 VisitForStackValue(args->at(0));
3182 __ CallStub(&stub); 3098 __ CallStub(&stub);
3183 decrement_stack_height();
3184 context()->Plug(eax); 3099 context()->Plug(eax);
3185 } 3100 }
3186 3101
3187 3102
3188 void FullCodeGenerator::EmitMathSqrt(ZoneList<Expression*>* args) { 3103 void FullCodeGenerator::EmitMathSqrt(ZoneList<Expression*>* args) {
3189 // Load the argument on the stack and call the runtime function. 3104 // Load the argument on the stack and call the runtime function.
3190 ASSERT(args->length() == 1); 3105 ASSERT(args->length() == 1);
3191 VisitForStackValue(args->at(0)); 3106 VisitForStackValue(args->at(0));
3192 __ CallRuntime(Runtime::kMath_sqrt, 1); 3107 __ CallRuntime(Runtime::kMath_sqrt, 1);
3193 decrement_stack_height();
3194 context()->Plug(eax); 3108 context()->Plug(eax);
3195 } 3109 }
3196 3110
3197 3111
3198 void FullCodeGenerator::EmitCallFunction(ZoneList<Expression*>* args) { 3112 void FullCodeGenerator::EmitCallFunction(ZoneList<Expression*>* args) {
3199 ASSERT(args->length() >= 2); 3113 ASSERT(args->length() >= 2);
3200 3114
3201 int arg_count = args->length() - 2; // 2 ~ receiver and function. 3115 int arg_count = args->length() - 2; // 2 ~ receiver and function.
3202 for (int i = 0; i < arg_count + 1; ++i) { 3116 for (int i = 0; i < arg_count + 1; ++i) {
3203 VisitForStackValue(args->at(i)); 3117 VisitForStackValue(args->at(i));
3204 } 3118 }
3205 VisitForAccumulatorValue(args->last()); // Function. 3119 VisitForAccumulatorValue(args->last()); // Function.
3206 3120
3207 // InvokeFunction requires the function in edi. Move it in there. 3121 // InvokeFunction requires the function in edi. Move it in there.
3208 __ mov(edi, result_register()); 3122 __ mov(edi, result_register());
3209 ParameterCount count(arg_count); 3123 ParameterCount count(arg_count);
3210 __ InvokeFunction(edi, count, CALL_FUNCTION, 3124 __ InvokeFunction(edi, count, CALL_FUNCTION,
3211 NullCallWrapper(), CALL_AS_METHOD); 3125 NullCallWrapper(), CALL_AS_METHOD);
3212 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 3126 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
3213 decrement_stack_height(arg_count + 1);
3214 context()->Plug(eax); 3127 context()->Plug(eax);
3215 } 3128 }
3216 3129
3217 3130
3218 void FullCodeGenerator::EmitRegExpConstructResult(ZoneList<Expression*>* args) { 3131 void FullCodeGenerator::EmitRegExpConstructResult(ZoneList<Expression*>* args) {
3219 // Load the arguments on the stack and call the stub. 3132 // Load the arguments on the stack and call the stub.
3220 RegExpConstructResultStub stub; 3133 RegExpConstructResultStub stub;
3221 ASSERT(args->length() == 3); 3134 ASSERT(args->length() == 3);
3222 VisitForStackValue(args->at(0)); 3135 VisitForStackValue(args->at(0));
3223 VisitForStackValue(args->at(1)); 3136 VisitForStackValue(args->at(1));
3224 VisitForStackValue(args->at(2)); 3137 VisitForStackValue(args->at(2));
3225 __ CallStub(&stub); 3138 __ CallStub(&stub);
3226 decrement_stack_height(3);
3227 context()->Plug(eax); 3139 context()->Plug(eax);
3228 } 3140 }
3229 3141
3230 3142
3231 void FullCodeGenerator::EmitSwapElements(ZoneList<Expression*>* args) { 3143 void FullCodeGenerator::EmitSwapElements(ZoneList<Expression*>* args) {
3232 ASSERT(args->length() == 3); 3144 ASSERT(args->length() == 3);
3233 VisitForStackValue(args->at(0)); 3145 VisitForStackValue(args->at(0));
3234 VisitForStackValue(args->at(1)); 3146 VisitForStackValue(args->at(1));
3235 VisitForStackValue(args->at(2)); 3147 VisitForStackValue(args->at(2));
3236 Label done; 3148 Label done;
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
3309 3221
3310 // We are done. Drop elements from the stack, and return undefined. 3222 // We are done. Drop elements from the stack, and return undefined.
3311 __ add(esp, Immediate(3 * kPointerSize)); 3223 __ add(esp, Immediate(3 * kPointerSize));
3312 __ mov(eax, isolate()->factory()->undefined_value()); 3224 __ mov(eax, isolate()->factory()->undefined_value());
3313 __ jmp(&done); 3225 __ jmp(&done);
3314 3226
3315 __ bind(&slow_case); 3227 __ bind(&slow_case);
3316 __ CallRuntime(Runtime::kSwapElements, 3); 3228 __ CallRuntime(Runtime::kSwapElements, 3);
3317 3229
3318 __ bind(&done); 3230 __ bind(&done);
3319 decrement_stack_height(3);
3320 context()->Plug(eax); 3231 context()->Plug(eax);
3321 } 3232 }
3322 3233
3323 3234
3324 void FullCodeGenerator::EmitGetFromCache(ZoneList<Expression*>* args) { 3235 void FullCodeGenerator::EmitGetFromCache(ZoneList<Expression*>* args) {
3325 ASSERT_EQ(2, args->length()); 3236 ASSERT_EQ(2, args->length());
3326 3237
3327 ASSERT_NE(NULL, args->at(0)->AsLiteral()); 3238 ASSERT_NE(NULL, args->at(0)->AsLiteral());
3328 int cache_id = Smi::cast(*(args->at(0)->AsLiteral()->handle()))->value(); 3239 int cache_id = Smi::cast(*(args->at(0)->AsLiteral()->handle()))->value();
3329 3240
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
3395 __ mov(tmp, FieldOperand(left, JSRegExp::kDataOffset)); 3306 __ mov(tmp, FieldOperand(left, JSRegExp::kDataOffset));
3396 __ cmp(tmp, FieldOperand(right, JSRegExp::kDataOffset)); 3307 __ cmp(tmp, FieldOperand(right, JSRegExp::kDataOffset));
3397 __ j(equal, &ok); 3308 __ j(equal, &ok);
3398 __ bind(&fail); 3309 __ bind(&fail);
3399 __ mov(eax, Immediate(isolate()->factory()->false_value())); 3310 __ mov(eax, Immediate(isolate()->factory()->false_value()));
3400 __ jmp(&done); 3311 __ jmp(&done);
3401 __ bind(&ok); 3312 __ bind(&ok);
3402 __ mov(eax, Immediate(isolate()->factory()->true_value())); 3313 __ mov(eax, Immediate(isolate()->factory()->true_value()));
3403 __ bind(&done); 3314 __ bind(&done);
3404 3315
3405 decrement_stack_height();
3406 context()->Plug(eax); 3316 context()->Plug(eax);
3407 } 3317 }
3408 3318
3409 3319
3410 void FullCodeGenerator::EmitHasCachedArrayIndex(ZoneList<Expression*>* args) { 3320 void FullCodeGenerator::EmitHasCachedArrayIndex(ZoneList<Expression*>* args) {
3411 ASSERT(args->length() == 1); 3321 ASSERT(args->length() == 1);
3412 3322
3413 VisitForAccumulatorValue(args->at(0)); 3323 VisitForAccumulatorValue(args->at(0));
3414 3324
3415 if (FLAG_debug_code) { 3325 if (FLAG_debug_code) {
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after
3699 3609
3700 3610
3701 __ bind(&bailout); 3611 __ bind(&bailout);
3702 __ mov(result_operand, isolate()->factory()->undefined_value()); 3612 __ mov(result_operand, isolate()->factory()->undefined_value());
3703 __ bind(&done); 3613 __ bind(&done);
3704 __ mov(eax, result_operand); 3614 __ mov(eax, result_operand);
3705 // Drop temp values from the stack, and restore context register. 3615 // Drop temp values from the stack, and restore context register.
3706 __ add(esp, Immediate(3 * kPointerSize)); 3616 __ add(esp, Immediate(3 * kPointerSize));
3707 3617
3708 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 3618 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
3709 decrement_stack_height();
3710 context()->Plug(eax); 3619 context()->Plug(eax);
3711 } 3620 }
3712 3621
3713 3622
3714 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { 3623 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
3715 Handle<String> name = expr->name(); 3624 Handle<String> name = expr->name();
3716 if (name->length() > 0 && name->Get(0) == '_') { 3625 if (name->length() > 0 && name->Get(0) == '_') {
3717 Comment cmnt(masm_, "[ InlineRuntimeCall"); 3626 Comment cmnt(masm_, "[ InlineRuntimeCall");
3718 EmitInlineRuntimeCall(expr); 3627 EmitInlineRuntimeCall(expr);
3719 return; 3628 return;
3720 } 3629 }
3721 3630
3722 Comment cmnt(masm_, "[ CallRuntime"); 3631 Comment cmnt(masm_, "[ CallRuntime");
3723 ZoneList<Expression*>* args = expr->arguments(); 3632 ZoneList<Expression*>* args = expr->arguments();
3724 3633
3725 if (expr->is_jsruntime()) { 3634 if (expr->is_jsruntime()) {
3726 // Prepare for calling JS runtime function. 3635 // Prepare for calling JS runtime function.
3727 __ mov(eax, GlobalObjectOperand()); 3636 __ mov(eax, GlobalObjectOperand());
3728 __ push(FieldOperand(eax, GlobalObject::kBuiltinsOffset)); 3637 __ push(FieldOperand(eax, GlobalObject::kBuiltinsOffset));
3729 increment_stack_height();
3730 } 3638 }
3731 3639
3732 // Push the arguments ("left-to-right"). 3640 // Push the arguments ("left-to-right").
3733 int arg_count = args->length(); 3641 int arg_count = args->length();
3734 for (int i = 0; i < arg_count; i++) { 3642 for (int i = 0; i < arg_count; i++) {
3735 VisitForStackValue(args->at(i)); 3643 VisitForStackValue(args->at(i));
3736 } 3644 }
3737 3645
3738 if (expr->is_jsruntime()) { 3646 if (expr->is_jsruntime()) {
3739 // Call the JS runtime function via a call IC. 3647 // Call the JS runtime function via a call IC.
3740 __ Set(ecx, Immediate(expr->name())); 3648 __ Set(ecx, Immediate(expr->name()));
3741 RelocInfo::Mode mode = RelocInfo::CODE_TARGET; 3649 RelocInfo::Mode mode = RelocInfo::CODE_TARGET;
3742 Handle<Code> ic = 3650 Handle<Code> ic =
3743 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); 3651 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode);
3744 __ call(ic, mode, expr->id()); 3652 __ call(ic, mode, expr->id());
3745 // Restore context register. 3653 // Restore context register.
3746 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 3654 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
3747 } else { 3655 } else {
3748 // Call the C runtime function. 3656 // Call the C runtime function.
3749 __ CallRuntime(expr->function(), arg_count); 3657 __ CallRuntime(expr->function(), arg_count);
3750 } 3658 }
3751 decrement_stack_height(arg_count);
3752 if (expr->is_jsruntime()) {
3753 decrement_stack_height();
3754 }
3755
3756 context()->Plug(eax); 3659 context()->Plug(eax);
3757 } 3660 }
3758 3661
3759 3662
3760 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { 3663 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
3761 switch (expr->op()) { 3664 switch (expr->op()) {
3762 case Token::DELETE: { 3665 case Token::DELETE: {
3763 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); 3666 Comment cmnt(masm_, "[ UnaryOperation (DELETE)");
3764 Property* property = expr->expression()->AsProperty(); 3667 Property* property = expr->expression()->AsProperty();
3765 VariableProxy* proxy = expr->expression()->AsVariableProxy(); 3668 VariableProxy* proxy = expr->expression()->AsVariableProxy();
3766 3669
3767 if (property != NULL) { 3670 if (property != NULL) {
3768 VisitForStackValue(property->obj()); 3671 VisitForStackValue(property->obj());
3769 VisitForStackValue(property->key()); 3672 VisitForStackValue(property->key());
3770 __ push(Immediate(Smi::FromInt(strict_mode_flag()))); 3673 __ push(Immediate(Smi::FromInt(strict_mode_flag())));
3771 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); 3674 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
3772 decrement_stack_height(2);
3773 context()->Plug(eax); 3675 context()->Plug(eax);
3774 } else if (proxy != NULL) { 3676 } else if (proxy != NULL) {
3775 Variable* var = proxy->var(); 3677 Variable* var = proxy->var();
3776 // Delete of an unqualified identifier is disallowed in strict mode 3678 // Delete of an unqualified identifier is disallowed in strict mode
3777 // but "delete this" is allowed. 3679 // but "delete this" is allowed.
3778 ASSERT(strict_mode_flag() == kNonStrictMode || var->is_this()); 3680 ASSERT(strict_mode_flag() == kNonStrictMode || var->is_this());
3779 if (var->IsUnallocated()) { 3681 if (var->IsUnallocated()) {
3780 __ push(GlobalObjectOperand()); 3682 __ push(GlobalObjectOperand());
3781 __ push(Immediate(var->name())); 3683 __ push(Immediate(var->name()));
3782 __ push(Immediate(Smi::FromInt(kNonStrictMode))); 3684 __ push(Immediate(Smi::FromInt(kNonStrictMode)));
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
3832 } 3734 }
3833 break; 3735 break;
3834 } 3736 }
3835 3737
3836 case Token::TYPEOF: { 3738 case Token::TYPEOF: {
3837 Comment cmnt(masm_, "[ UnaryOperation (TYPEOF)"); 3739 Comment cmnt(masm_, "[ UnaryOperation (TYPEOF)");
3838 { StackValueContext context(this); 3740 { StackValueContext context(this);
3839 VisitForTypeofValue(expr->expression()); 3741 VisitForTypeofValue(expr->expression());
3840 } 3742 }
3841 __ CallRuntime(Runtime::kTypeof, 1); 3743 __ CallRuntime(Runtime::kTypeof, 1);
3842 decrement_stack_height();
3843 context()->Plug(eax); 3744 context()->Plug(eax);
3844 break; 3745 break;
3845 } 3746 }
3846 3747
3847 case Token::ADD: { 3748 case Token::ADD: {
3848 Comment cmt(masm_, "[ UnaryOperation (ADD)"); 3749 Comment cmt(masm_, "[ UnaryOperation (ADD)");
3849 VisitForAccumulatorValue(expr->expression()); 3750 VisitForAccumulatorValue(expr->expression());
3850 Label no_conversion; 3751 Label no_conversion;
3851 __ JumpIfSmi(result_register(), &no_conversion); 3752 __ JumpIfSmi(result_register(), &no_conversion);
3852 ToNumberStub convert_stub; 3753 ToNumberStub convert_stub;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
3886 } 3787 }
3887 3788
3888 3789
3889 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { 3790 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
3890 Comment cmnt(masm_, "[ CountOperation"); 3791 Comment cmnt(masm_, "[ CountOperation");
3891 SetSourcePosition(expr->position()); 3792 SetSourcePosition(expr->position());
3892 3793
3893 // Invalid left-hand sides are rewritten to have a 'throw ReferenceError' 3794 // Invalid left-hand sides are rewritten to have a 'throw ReferenceError'
3894 // as the left-hand side. 3795 // as the left-hand side.
3895 if (!expr->expression()->IsValidLeftHandSide()) { 3796 if (!expr->expression()->IsValidLeftHandSide()) {
3896 ASSERT(expr->expression()->AsThrow() != NULL); 3797 VisitForEffect(expr->expression());
3897 VisitInCurrentContext(expr->expression());
3898 // Visiting Throw does not plug the context.
3899 context()->Plug(eax);
3900 return; 3798 return;
3901 } 3799 }
3902 3800
3903 // Expression can only be a property, a global or a (parameter or local) 3801 // Expression can only be a property, a global or a (parameter or local)
3904 // slot. 3802 // slot.
3905 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; 3803 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
3906 LhsKind assign_type = VARIABLE; 3804 LhsKind assign_type = VARIABLE;
3907 Property* prop = expr->expression()->AsProperty(); 3805 Property* prop = expr->expression()->AsProperty();
3908 // In case of a property we use the uninitialized expression context 3806 // In case of a property we use the uninitialized expression context
3909 // of the key to detect a named property. 3807 // of the key to detect a named property.
3910 if (prop != NULL) { 3808 if (prop != NULL) {
3911 assign_type = 3809 assign_type =
3912 (prop->key()->IsPropertyName()) ? NAMED_PROPERTY : KEYED_PROPERTY; 3810 (prop->key()->IsPropertyName()) ? NAMED_PROPERTY : KEYED_PROPERTY;
3913 } 3811 }
3914 3812
3915 // Evaluate expression and get value. 3813 // Evaluate expression and get value.
3916 if (assign_type == VARIABLE) { 3814 if (assign_type == VARIABLE) {
3917 ASSERT(expr->expression()->AsVariableProxy()->var() != NULL); 3815 ASSERT(expr->expression()->AsVariableProxy()->var() != NULL);
3918 AccumulatorValueContext context(this); 3816 AccumulatorValueContext context(this);
3919 EmitVariableLoad(expr->expression()->AsVariableProxy()); 3817 EmitVariableLoad(expr->expression()->AsVariableProxy());
3920 } else { 3818 } else {
3921 // Reserve space for result of postfix operation. 3819 // Reserve space for result of postfix operation.
3922 if (expr->is_postfix() && !context()->IsEffect()) { 3820 if (expr->is_postfix() && !context()->IsEffect()) {
3923 __ push(Immediate(Smi::FromInt(0))); 3821 __ push(Immediate(Smi::FromInt(0)));
3924 increment_stack_height();
3925 } 3822 }
3926 if (assign_type == NAMED_PROPERTY) { 3823 if (assign_type == NAMED_PROPERTY) {
3927 // Put the object both on the stack and in the accumulator. 3824 // Put the object both on the stack and in the accumulator.
3928 VisitForAccumulatorValue(prop->obj()); 3825 VisitForAccumulatorValue(prop->obj());
3929 __ push(eax); 3826 __ push(eax);
3930 increment_stack_height();
3931 EmitNamedPropertyLoad(prop); 3827 EmitNamedPropertyLoad(prop);
3932 } else { 3828 } else {
3933 VisitForStackValue(prop->obj()); 3829 VisitForStackValue(prop->obj());
3934 VisitForAccumulatorValue(prop->key()); 3830 VisitForAccumulatorValue(prop->key());
3935 __ mov(edx, Operand(esp, 0)); 3831 __ mov(edx, Operand(esp, 0));
3936 __ push(eax); 3832 __ push(eax);
3937 increment_stack_height();
3938 EmitKeyedPropertyLoad(prop); 3833 EmitKeyedPropertyLoad(prop);
3939 } 3834 }
3940 } 3835 }
3941 3836
3942 // We need a second deoptimization point after loading the value 3837 // We need a second deoptimization point after loading the value
3943 // in case evaluating the property load my have a side effect. 3838 // in case evaluating the property load my have a side effect.
3944 if (assign_type == VARIABLE) { 3839 if (assign_type == VARIABLE) {
3945 PrepareForBailout(expr->expression(), TOS_REG); 3840 PrepareForBailout(expr->expression(), TOS_REG);
3946 } else { 3841 } else {
3947 PrepareForBailoutForId(expr->CountId(), TOS_REG); 3842 PrepareForBailoutForId(expr->CountId(), TOS_REG);
(...skipping 10 matching lines...) Expand all
3958 3853
3959 // Save result for postfix expressions. 3854 // Save result for postfix expressions.
3960 if (expr->is_postfix()) { 3855 if (expr->is_postfix()) {
3961 if (!context()->IsEffect()) { 3856 if (!context()->IsEffect()) {
3962 // Save the result on the stack. If we have a named or keyed property 3857 // Save the result on the stack. If we have a named or keyed property
3963 // we store the result under the receiver that is currently on top 3858 // we store the result under the receiver that is currently on top
3964 // of the stack. 3859 // of the stack.
3965 switch (assign_type) { 3860 switch (assign_type) {
3966 case VARIABLE: 3861 case VARIABLE:
3967 __ push(eax); 3862 __ push(eax);
3968 increment_stack_height();
3969 break; 3863 break;
3970 case NAMED_PROPERTY: 3864 case NAMED_PROPERTY:
3971 __ mov(Operand(esp, kPointerSize), eax); 3865 __ mov(Operand(esp, kPointerSize), eax);
3972 break; 3866 break;
3973 case KEYED_PROPERTY: 3867 case KEYED_PROPERTY:
3974 __ mov(Operand(esp, 2 * kPointerSize), eax); 3868 __ mov(Operand(esp, 2 * kPointerSize), eax);
3975 break; 3869 break;
3976 } 3870 }
3977 } 3871 }
3978 } 3872 }
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
4032 // Perform the assignment as if via '='. 3926 // Perform the assignment as if via '='.
4033 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 3927 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
4034 Token::ASSIGN); 3928 Token::ASSIGN);
4035 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3929 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4036 context()->Plug(eax); 3930 context()->Plug(eax);
4037 } 3931 }
4038 break; 3932 break;
4039 case NAMED_PROPERTY: { 3933 case NAMED_PROPERTY: {
4040 __ mov(ecx, prop->key()->AsLiteral()->handle()); 3934 __ mov(ecx, prop->key()->AsLiteral()->handle());
4041 __ pop(edx); 3935 __ pop(edx);
4042 decrement_stack_height();
4043 Handle<Code> ic = is_strict_mode() 3936 Handle<Code> ic = is_strict_mode()
4044 ? isolate()->builtins()->StoreIC_Initialize_Strict() 3937 ? isolate()->builtins()->StoreIC_Initialize_Strict()
4045 : isolate()->builtins()->StoreIC_Initialize(); 3938 : isolate()->builtins()->StoreIC_Initialize();
4046 __ call(ic, RelocInfo::CODE_TARGET, expr->id()); 3939 __ call(ic, RelocInfo::CODE_TARGET, expr->id());
4047 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3940 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4048 if (expr->is_postfix()) { 3941 if (expr->is_postfix()) {
4049 if (!context()->IsEffect()) { 3942 if (!context()->IsEffect()) {
4050 context()->PlugTOS(); 3943 context()->PlugTOS();
4051 } 3944 }
4052 } else { 3945 } else {
4053 context()->Plug(eax); 3946 context()->Plug(eax);
4054 } 3947 }
4055 break; 3948 break;
4056 } 3949 }
4057 case KEYED_PROPERTY: { 3950 case KEYED_PROPERTY: {
4058 __ pop(ecx); 3951 __ pop(ecx);
4059 __ pop(edx); 3952 __ pop(edx);
4060 decrement_stack_height();
4061 decrement_stack_height();
4062 Handle<Code> ic = is_strict_mode() 3953 Handle<Code> ic = is_strict_mode()
4063 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 3954 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
4064 : isolate()->builtins()->KeyedStoreIC_Initialize(); 3955 : isolate()->builtins()->KeyedStoreIC_Initialize();
4065 __ call(ic, RelocInfo::CODE_TARGET, expr->id()); 3956 __ call(ic, RelocInfo::CODE_TARGET, expr->id());
4066 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3957 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4067 if (expr->is_postfix()) { 3958 if (expr->is_postfix()) {
4068 // Result is on the stack 3959 // Result is on the stack
4069 if (!context()->IsEffect()) { 3960 if (!context()->IsEffect()) {
4070 context()->PlugTOS(); 3961 context()->PlugTOS();
4071 } 3962 }
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
4204 Label* fall_through = NULL; 4095 Label* fall_through = NULL;
4205 context()->PrepareTest(&materialize_true, &materialize_false, 4096 context()->PrepareTest(&materialize_true, &materialize_false,
4206 &if_true, &if_false, &fall_through); 4097 &if_true, &if_false, &fall_through);
4207 4098
4208 Token::Value op = expr->op(); 4099 Token::Value op = expr->op();
4209 VisitForStackValue(expr->left()); 4100 VisitForStackValue(expr->left());
4210 switch (op) { 4101 switch (op) {
4211 case Token::IN: 4102 case Token::IN:
4212 VisitForStackValue(expr->right()); 4103 VisitForStackValue(expr->right());
4213 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION); 4104 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION);
4214 decrement_stack_height(2);
4215 PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL); 4105 PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL);
4216 __ cmp(eax, isolate()->factory()->true_value()); 4106 __ cmp(eax, isolate()->factory()->true_value());
4217 Split(equal, if_true, if_false, fall_through); 4107 Split(equal, if_true, if_false, fall_through);
4218 break; 4108 break;
4219 4109
4220 case Token::INSTANCEOF: { 4110 case Token::INSTANCEOF: {
4221 VisitForStackValue(expr->right()); 4111 VisitForStackValue(expr->right());
4222 InstanceofStub stub(InstanceofStub::kNoFlags); 4112 InstanceofStub stub(InstanceofStub::kNoFlags);
4223 __ CallStub(&stub); 4113 __ CallStub(&stub);
4224 decrement_stack_height(2);
4225 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); 4114 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
4226 __ test(eax, eax); 4115 __ test(eax, eax);
4227 // The stub returns 0 for true. 4116 // The stub returns 0 for true.
4228 Split(zero, if_true, if_false, fall_through); 4117 Split(zero, if_true, if_false, fall_through);
4229 break; 4118 break;
4230 } 4119 }
4231 4120
4232 default: { 4121 default: {
4233 VisitForAccumulatorValue(expr->right()); 4122 VisitForAccumulatorValue(expr->right());
4234 Condition cc = no_condition; 4123 Condition cc = no_condition;
(...skipping 13 matching lines...) Expand all
4248 break; 4137 break;
4249 case Token::GTE: 4138 case Token::GTE:
4250 cc = greater_equal; 4139 cc = greater_equal;
4251 break; 4140 break;
4252 case Token::IN: 4141 case Token::IN:
4253 case Token::INSTANCEOF: 4142 case Token::INSTANCEOF:
4254 default: 4143 default:
4255 UNREACHABLE(); 4144 UNREACHABLE();
4256 } 4145 }
4257 __ pop(edx); 4146 __ pop(edx);
4258 decrement_stack_height();
4259 4147
4260 bool inline_smi_code = ShouldInlineSmiCase(op); 4148 bool inline_smi_code = ShouldInlineSmiCase(op);
4261 JumpPatchSite patch_site(masm_); 4149 JumpPatchSite patch_site(masm_);
4262 if (inline_smi_code) { 4150 if (inline_smi_code) {
4263 Label slow_case; 4151 Label slow_case;
4264 __ mov(ecx, edx); 4152 __ mov(ecx, edx);
4265 __ or_(ecx, eax); 4153 __ or_(ecx, eax);
4266 patch_site.EmitJumpIfNotSmi(ecx, &slow_case, Label::kNear); 4154 patch_site.EmitJumpIfNotSmi(ecx, &slow_case, Label::kNear);
4267 __ cmp(edx, eax); 4155 __ cmp(edx, eax);
4268 Split(cc, if_true, if_false, NULL); 4156 Split(cc, if_true, if_false, NULL);
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
4424 *context_length = 0; 4312 *context_length = 0;
4425 return previous_; 4313 return previous_;
4426 } 4314 }
4427 4315
4428 4316
4429 #undef __ 4317 #undef __
4430 4318
4431 } } // namespace v8::internal 4319 } } // namespace v8::internal
4432 4320
4433 #endif // V8_TARGET_ARCH_IA32 4321 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/full-codegen.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698