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

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.
1662 if (expr->is_compound()) { 1619 if (expr->is_compound()) {
1663 AccumulatorValueContext result_context(this); 1620 { AccumulatorValueContext context(this);
1664 { AccumulatorValueContext left_operand_context(this);
1665 switch (assign_type) { 1621 switch (assign_type) {
1666 case VARIABLE: 1622 case VARIABLE:
1667 EmitVariableLoad(expr->target()->AsVariableProxy()); 1623 EmitVariableLoad(expr->target()->AsVariableProxy());
1668 PrepareForBailout(expr->target(), TOS_REG); 1624 PrepareForBailout(expr->target(), TOS_REG);
1669 break; 1625 break;
1670 case NAMED_PROPERTY: 1626 case NAMED_PROPERTY:
1671 EmitNamedPropertyLoad(property); 1627 EmitNamedPropertyLoad(property);
1672 PrepareForBailoutForId(expr->CompoundLoadId(), TOS_REG); 1628 PrepareForBailoutForId(expr->CompoundLoadId(), TOS_REG);
1673 break; 1629 break;
1674 case KEYED_PROPERTY: 1630 case KEYED_PROPERTY:
1675 EmitKeyedPropertyLoad(property); 1631 EmitKeyedPropertyLoad(property);
1676 PrepareForBailoutForId(expr->CompoundLoadId(), TOS_REG); 1632 PrepareForBailoutForId(expr->CompoundLoadId(), TOS_REG);
1677 break; 1633 break;
1678 } 1634 }
1679 } 1635 }
1680 1636
1681 Token::Value op = expr->binary_op(); 1637 Token::Value op = expr->binary_op();
1682 __ push(eax); // Left operand goes on the stack. 1638 __ push(eax); // Left operand goes on the stack.
1683 increment_stack_height();
1684 VisitForAccumulatorValue(expr->value()); 1639 VisitForAccumulatorValue(expr->value());
1685 1640
1686 OverwriteMode mode = expr->value()->ResultOverwriteAllowed() 1641 OverwriteMode mode = expr->value()->ResultOverwriteAllowed()
1687 ? OVERWRITE_RIGHT 1642 ? OVERWRITE_RIGHT
1688 : NO_OVERWRITE; 1643 : NO_OVERWRITE;
1689 SetSourcePosition(expr->position() + 1); 1644 SetSourcePosition(expr->position() + 1);
1645 AccumulatorValueContext context(this);
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,
1694 expr->target(), 1650 expr->target(),
1695 expr->value()); 1651 expr->value());
1696 } else { 1652 } else {
1697 EmitBinaryOp(expr->binary_operation(), op, mode); 1653 EmitBinaryOp(expr->binary_operation(), op, mode);
1698 } 1654 }
1699 1655
(...skipping 43 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 21 matching lines...) Expand all
2202 isolate()->factory()->NewJSGlobalPropertyCell(uninitialized); 2140 isolate()->factory()->NewJSGlobalPropertyCell(uninitialized);
2203 __ test(eax, Immediate(cell)); 2141 __ test(eax, Immediate(cell));
2204 // Patching code in the stub assumes the opcode is 1 byte and there is 2142 // Patching code in the stub assumes the opcode is 1 byte and there is
2205 // word for a pointer in the operand. 2143 // word for a pointer in the operand.
2206 ASSERT(masm()->pc_offset() - return_site_offset >= 1 + kPointerSize); 2144 ASSERT(masm()->pc_offset() - return_site_offset >= 1 + kPointerSize);
2207 } 2145 }
2208 2146
2209 RecordJSReturnSite(expr); 2147 RecordJSReturnSite(expr);
2210 // Restore context register. 2148 // Restore context register.
2211 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2149 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2212
2213 decrement_stack_height(arg_count + 1);
2214 context()->DropAndPlug(1, eax); 2150 context()->DropAndPlug(1, eax);
2215 } 2151 }
2216 2152
2217 2153
2218 void FullCodeGenerator::EmitResolvePossiblyDirectEval(ResolveEvalFlag flag, 2154 void FullCodeGenerator::EmitResolvePossiblyDirectEval(ResolveEvalFlag flag,
2219 int arg_count) { 2155 int arg_count) {
2220 // Push copy of the first argument or undefined if it doesn't exist. 2156 // Push copy of the first argument or undefined if it doesn't exist.
2221 if (arg_count > 0) { 2157 if (arg_count > 0) {
2222 __ push(Operand(esp, arg_count * kPointerSize)); 2158 __ push(Operand(esp, arg_count * kPointerSize));
2223 } else { 2159 } else {
(...skipping 30 matching lines...) Expand all
2254 if (proxy != NULL && proxy->var()->is_possibly_eval()) { 2190 if (proxy != NULL && proxy->var()->is_possibly_eval()) {
2255 // In a call to eval, we first call %ResolvePossiblyDirectEval to 2191 // In a call to eval, we first call %ResolvePossiblyDirectEval to
2256 // resolve the function we need to call and the receiver of the call. 2192 // resolve the function we need to call and the receiver of the call.
2257 // Then we call the resolved function using the given arguments. 2193 // Then we call the resolved function using the given arguments.
2258 ZoneList<Expression*>* args = expr->arguments(); 2194 ZoneList<Expression*>* args = expr->arguments();
2259 int arg_count = args->length(); 2195 int arg_count = args->length();
2260 { PreservePositionScope pos_scope(masm()->positions_recorder()); 2196 { PreservePositionScope pos_scope(masm()->positions_recorder());
2261 VisitForStackValue(callee); 2197 VisitForStackValue(callee);
2262 // Reserved receiver slot. 2198 // Reserved receiver slot.
2263 __ push(Immediate(isolate()->factory()->undefined_value())); 2199 __ push(Immediate(isolate()->factory()->undefined_value()));
2264 increment_stack_height(); 2200
fschneider 2011/11/01 12:12:07 Empty line.
2265 // Push the arguments. 2201 // Push the arguments.
2266 for (int i = 0; i < arg_count; i++) { 2202 for (int i = 0; i < arg_count; i++) {
2267 VisitForStackValue(args->at(i)); 2203 VisitForStackValue(args->at(i));
2268 } 2204 }
2269 2205
2270 // If we know that eval can only be shadowed by eval-introduced 2206 // If we know that eval can only be shadowed by eval-introduced
2271 // variables we attempt to load the global eval function directly in 2207 // variables we attempt to load the global eval function directly in
2272 // generated code. If we succeed, there is no need to perform a 2208 // generated code. If we succeed, there is no need to perform a
2273 // context lookup in the runtime system. 2209 // context lookup in the runtime system.
2274 Label done; 2210 Label done;
(...skipping 19 matching lines...) Expand all
2294 __ mov(Operand(esp, (arg_count + 0) * kPointerSize), edx); 2230 __ mov(Operand(esp, (arg_count + 0) * kPointerSize), edx);
2295 __ mov(Operand(esp, (arg_count + 1) * kPointerSize), eax); 2231 __ mov(Operand(esp, (arg_count + 1) * kPointerSize), eax);
2296 } 2232 }
2297 // Record source position for debugger. 2233 // Record source position for debugger.
2298 SetSourcePosition(expr->position()); 2234 SetSourcePosition(expr->position());
2299 CallFunctionStub stub(arg_count, RECEIVER_MIGHT_BE_IMPLICIT); 2235 CallFunctionStub stub(arg_count, RECEIVER_MIGHT_BE_IMPLICIT);
2300 __ CallStub(&stub); 2236 __ CallStub(&stub);
2301 RecordJSReturnSite(expr); 2237 RecordJSReturnSite(expr);
2302 // Restore context register. 2238 // Restore context register.
2303 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2239 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2304 decrement_stack_height(arg_count + 1); // Function is left on the stack.
2305 context()->DropAndPlug(1, eax); 2240 context()->DropAndPlug(1, eax);
2306 2241
2307 } else if (proxy != NULL && proxy->var()->IsUnallocated()) { 2242 } else if (proxy != NULL && proxy->var()->IsUnallocated()) {
2308 // Push global object as receiver for the call IC. 2243 // Push global object as receiver for the call IC.
2309 __ push(GlobalObjectOperand()); 2244 __ push(GlobalObjectOperand());
2310 increment_stack_height();
2311 EmitCallWithIC(expr, proxy->name(), RelocInfo::CODE_TARGET_CONTEXT); 2245 EmitCallWithIC(expr, proxy->name(), RelocInfo::CODE_TARGET_CONTEXT);
2312 2246
2313 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { 2247 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) {
2314 // Call to a lookup slot (dynamically introduced variable). 2248 // Call to a lookup slot (dynamically introduced variable).
2315 Label slow, done; 2249 Label slow, done;
2316 { PreservePositionScope scope(masm()->positions_recorder()); 2250 { PreservePositionScope scope(masm()->positions_recorder());
2317 // Generate code for loading from variables potentially shadowed by 2251 // Generate code for loading from variables potentially shadowed by
2318 // eval-introduced variables. 2252 // eval-introduced variables.
2319 EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done); 2253 EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done);
2320 } 2254 }
2321 __ bind(&slow); 2255 __ bind(&slow);
2322 // Call the runtime to find the function to call (returned in eax) and 2256 // Call the runtime to find the function to call (returned in eax) and
2323 // the object holding it (returned in edx). 2257 // the object holding it (returned in edx).
2324 __ push(context_register()); 2258 __ push(context_register());
2325 __ push(Immediate(proxy->name())); 2259 __ push(Immediate(proxy->name()));
2326 __ CallRuntime(Runtime::kLoadContextSlot, 2); 2260 __ CallRuntime(Runtime::kLoadContextSlot, 2);
2327 __ push(eax); // Function. 2261 __ push(eax); // Function.
2328 __ push(edx); // Receiver. 2262 __ push(edx); // Receiver.
2329 increment_stack_height(2);
2330 2263
2331 // If fast case code has been generated, emit code to push the function 2264 // If fast case code has been generated, emit code to push the function
2332 // and receiver and have the slow path jump around this code. 2265 // and receiver and have the slow path jump around this code.
2333 if (done.is_linked()) { 2266 if (done.is_linked()) {
2334 Label call; 2267 Label call;
2335 __ jmp(&call, Label::kNear); 2268 __ jmp(&call, Label::kNear);
2336 __ bind(&done); 2269 __ bind(&done);
2337 // Push function. Stack height already incremented in slow case 2270 // Push function.
2338 // above.
2339 __ push(eax); 2271 __ push(eax);
2340 // The receiver is implicitly the global receiver. Indicate this by 2272 // The receiver is implicitly the global receiver. Indicate this by
2341 // passing the hole to the call function stub. 2273 // passing the hole to the call function stub.
2342 __ push(Immediate(isolate()->factory()->the_hole_value())); 2274 __ push(Immediate(isolate()->factory()->the_hole_value()));
2343 __ bind(&call); 2275 __ bind(&call);
2344 } 2276 }
2345 2277
2346 // The receiver is either the global receiver or an object found by 2278 // The receiver is either the global receiver or an object found by
2347 // LoadContextSlot. That object could be the hole if the receiver is 2279 // LoadContextSlot. That object could be the hole if the receiver is
2348 // implicitly the global object. 2280 // implicitly the global object.
(...skipping 12 matching lines...) Expand all
2361 } 2293 }
2362 2294
2363 } else { 2295 } else {
2364 // Call to an arbitrary expression not handled specially above. 2296 // Call to an arbitrary expression not handled specially above.
2365 { PreservePositionScope scope(masm()->positions_recorder()); 2297 { PreservePositionScope scope(masm()->positions_recorder());
2366 VisitForStackValue(callee); 2298 VisitForStackValue(callee);
2367 } 2299 }
2368 // Load global receiver object. 2300 // Load global receiver object.
2369 __ mov(ebx, GlobalObjectOperand()); 2301 __ mov(ebx, GlobalObjectOperand());
2370 __ push(FieldOperand(ebx, GlobalObject::kGlobalReceiverOffset)); 2302 __ push(FieldOperand(ebx, GlobalObject::kGlobalReceiverOffset));
2371 increment_stack_height();
2372 // Emit function call. 2303 // Emit function call.
2373 EmitCallWithStub(expr, NO_CALL_FUNCTION_FLAGS); 2304 EmitCallWithStub(expr, NO_CALL_FUNCTION_FLAGS);
2374 } 2305 }
2375 2306
2376 #ifdef DEBUG 2307 #ifdef DEBUG
2377 // RecordJSReturnSite should have been called. 2308 // RecordJSReturnSite should have been called.
2378 ASSERT(expr->return_is_recorded_); 2309 ASSERT(expr->return_is_recorded_);
2379 #endif 2310 #endif
2380 } 2311 }
2381 2312
(...skipping 20 matching lines...) Expand all
2402 // constructor invocation. 2333 // constructor invocation.
2403 SetSourcePosition(expr->position()); 2334 SetSourcePosition(expr->position());
2404 2335
2405 // Load function and argument count into edi and eax. 2336 // Load function and argument count into edi and eax.
2406 __ SafeSet(eax, Immediate(arg_count)); 2337 __ SafeSet(eax, Immediate(arg_count));
2407 __ mov(edi, Operand(esp, arg_count * kPointerSize)); 2338 __ mov(edi, Operand(esp, arg_count * kPointerSize));
2408 2339
2409 Handle<Code> construct_builtin = 2340 Handle<Code> construct_builtin =
2410 isolate()->builtins()->JSConstructCall(); 2341 isolate()->builtins()->JSConstructCall();
2411 __ call(construct_builtin, RelocInfo::CONSTRUCT_CALL); 2342 __ call(construct_builtin, RelocInfo::CONSTRUCT_CALL);
2412
2413 decrement_stack_height(arg_count + 1);
2414 context()->Plug(eax); 2343 context()->Plug(eax);
2415 } 2344 }
2416 2345
2417 2346
2418 void FullCodeGenerator::EmitIsSmi(ZoneList<Expression*>* args) { 2347 void FullCodeGenerator::EmitIsSmi(ZoneList<Expression*>* args) {
2419 ASSERT(args->length() == 1); 2348 ASSERT(args->length() == 1);
2420 2349
2421 VisitForAccumulatorValue(args->at(0)); 2350 VisitForAccumulatorValue(args->at(0));
2422 2351
2423 Label materialize_true, materialize_false; 2352 Label materialize_true, materialize_false;
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after
2716 VisitForAccumulatorValue(args->at(1)); 2645 VisitForAccumulatorValue(args->at(1));
2717 2646
2718 Label materialize_true, materialize_false; 2647 Label materialize_true, materialize_false;
2719 Label* if_true = NULL; 2648 Label* if_true = NULL;
2720 Label* if_false = NULL; 2649 Label* if_false = NULL;
2721 Label* fall_through = NULL; 2650 Label* fall_through = NULL;
2722 context()->PrepareTest(&materialize_true, &materialize_false, 2651 context()->PrepareTest(&materialize_true, &materialize_false,
2723 &if_true, &if_false, &fall_through); 2652 &if_true, &if_false, &fall_through);
2724 2653
2725 __ pop(ebx); 2654 __ pop(ebx);
2726 decrement_stack_height();
2727 __ cmp(eax, ebx); 2655 __ cmp(eax, ebx);
2728 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); 2656 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
2729 Split(equal, if_true, if_false, fall_through); 2657 Split(equal, if_true, if_false, fall_through);
2730 2658
2731 context()->Plug(if_true, if_false); 2659 context()->Plug(if_true, if_false);
2732 } 2660 }
2733 2661
2734 2662
2735 void FullCodeGenerator::EmitArguments(ZoneList<Expression*>* args) { 2663 void FullCodeGenerator::EmitArguments(ZoneList<Expression*>* args) {
2736 ASSERT(args->length() == 1); 2664 ASSERT(args->length() == 1);
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
2835 // 0 (literal string): The type of logging (corresponds to the flags). 2763 // 0 (literal string): The type of logging (corresponds to the flags).
2836 // This is used to determine whether or not to generate the log call. 2764 // This is used to determine whether or not to generate the log call.
2837 // 1 (string): Format string. Access the string at argument index 2 2765 // 1 (string): Format string. Access the string at argument index 2
2838 // with '%2s' (see Logger::LogRuntime for all the formats). 2766 // with '%2s' (see Logger::LogRuntime for all the formats).
2839 // 2 (array): Arguments to the format string. 2767 // 2 (array): Arguments to the format string.
2840 ASSERT_EQ(args->length(), 3); 2768 ASSERT_EQ(args->length(), 3);
2841 if (CodeGenerator::ShouldGenerateLog(args->at(0))) { 2769 if (CodeGenerator::ShouldGenerateLog(args->at(0))) {
2842 VisitForStackValue(args->at(1)); 2770 VisitForStackValue(args->at(1));
2843 VisitForStackValue(args->at(2)); 2771 VisitForStackValue(args->at(2));
2844 __ CallRuntime(Runtime::kLog, 2); 2772 __ CallRuntime(Runtime::kLog, 2);
2845 decrement_stack_height(2);
2846 } 2773 }
2847 // Finally, we're expected to leave a value on the top of the stack. 2774 // Finally, we're expected to leave a value on the top of the stack.
2848 __ mov(eax, isolate()->factory()->undefined_value()); 2775 __ mov(eax, isolate()->factory()->undefined_value());
2849 context()->Plug(eax); 2776 context()->Plug(eax);
2850 } 2777 }
2851 2778
2852 2779
2853 void FullCodeGenerator::EmitRandomHeapNumber(ZoneList<Expression*>* args) { 2780 void FullCodeGenerator::EmitRandomHeapNumber(ZoneList<Expression*>* args) {
2854 ASSERT(args->length() == 0); 2781 ASSERT(args->length() == 0);
2855 2782
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
2902 2829
2903 2830
2904 void FullCodeGenerator::EmitSubString(ZoneList<Expression*>* args) { 2831 void FullCodeGenerator::EmitSubString(ZoneList<Expression*>* args) {
2905 // Load the arguments on the stack and call the stub. 2832 // Load the arguments on the stack and call the stub.
2906 SubStringStub stub; 2833 SubStringStub stub;
2907 ASSERT(args->length() == 3); 2834 ASSERT(args->length() == 3);
2908 VisitForStackValue(args->at(0)); 2835 VisitForStackValue(args->at(0));
2909 VisitForStackValue(args->at(1)); 2836 VisitForStackValue(args->at(1));
2910 VisitForStackValue(args->at(2)); 2837 VisitForStackValue(args->at(2));
2911 __ CallStub(&stub); 2838 __ CallStub(&stub);
2912 decrement_stack_height(3);
2913 context()->Plug(eax); 2839 context()->Plug(eax);
2914 } 2840 }
2915 2841
2916 2842
2917 void FullCodeGenerator::EmitRegExpExec(ZoneList<Expression*>* args) { 2843 void FullCodeGenerator::EmitRegExpExec(ZoneList<Expression*>* args) {
2918 // Load the arguments on the stack and call the stub. 2844 // Load the arguments on the stack and call the stub.
2919 RegExpExecStub stub; 2845 RegExpExecStub stub;
2920 ASSERT(args->length() == 4); 2846 ASSERT(args->length() == 4);
2921 VisitForStackValue(args->at(0)); 2847 VisitForStackValue(args->at(0));
2922 VisitForStackValue(args->at(1)); 2848 VisitForStackValue(args->at(1));
2923 VisitForStackValue(args->at(2)); 2849 VisitForStackValue(args->at(2));
2924 VisitForStackValue(args->at(3)); 2850 VisitForStackValue(args->at(3));
2925 __ CallStub(&stub); 2851 __ CallStub(&stub);
2926 decrement_stack_height(4);
2927 context()->Plug(eax); 2852 context()->Plug(eax);
2928 } 2853 }
2929 2854
2930 2855
2931 void FullCodeGenerator::EmitValueOf(ZoneList<Expression*>* args) { 2856 void FullCodeGenerator::EmitValueOf(ZoneList<Expression*>* args) {
2932 ASSERT(args->length() == 1); 2857 ASSERT(args->length() == 1);
2933 2858
2934 VisitForAccumulatorValue(args->at(0)); // Load the object. 2859 VisitForAccumulatorValue(args->at(0)); // Load the object.
2935 2860
2936 Label done; 2861 Label done;
(...skipping 14 matching lines...) Expand all
2951 ASSERT(args->length() == 2); 2876 ASSERT(args->length() == 2);
2952 VisitForStackValue(args->at(0)); 2877 VisitForStackValue(args->at(0));
2953 VisitForStackValue(args->at(1)); 2878 VisitForStackValue(args->at(1));
2954 2879
2955 if (CpuFeatures::IsSupported(SSE2)) { 2880 if (CpuFeatures::IsSupported(SSE2)) {
2956 MathPowStub stub; 2881 MathPowStub stub;
2957 __ CallStub(&stub); 2882 __ CallStub(&stub);
2958 } else { 2883 } else {
2959 __ CallRuntime(Runtime::kMath_pow, 2); 2884 __ CallRuntime(Runtime::kMath_pow, 2);
2960 } 2885 }
2961 decrement_stack_height(2);
2962 context()->Plug(eax); 2886 context()->Plug(eax);
2963 } 2887 }
2964 2888
2965 2889
2966 void FullCodeGenerator::EmitSetValueOf(ZoneList<Expression*>* args) { 2890 void FullCodeGenerator::EmitSetValueOf(ZoneList<Expression*>* args) {
2967 ASSERT(args->length() == 2); 2891 ASSERT(args->length() == 2);
2968 2892
2969 VisitForStackValue(args->at(0)); // Load the object. 2893 VisitForStackValue(args->at(0)); // Load the object.
2970 VisitForAccumulatorValue(args->at(1)); // Load the value. 2894 VisitForAccumulatorValue(args->at(1)); // Load the value.
2971 __ pop(ebx); // eax = value. ebx = object. 2895 __ pop(ebx); // eax = value. ebx = object.
2972 decrement_stack_height();
2973 2896
2974 Label done; 2897 Label done;
2975 // If the object is a smi, return the value. 2898 // If the object is a smi, return the value.
2976 __ JumpIfSmi(ebx, &done, Label::kNear); 2899 __ JumpIfSmi(ebx, &done, Label::kNear);
2977 2900
2978 // If the object is not a value type, return the value. 2901 // If the object is not a value type, return the value.
2979 __ CmpObjectType(ebx, JS_VALUE_TYPE, ecx); 2902 __ CmpObjectType(ebx, JS_VALUE_TYPE, ecx);
2980 __ j(not_equal, &done, Label::kNear); 2903 __ j(not_equal, &done, Label::kNear);
2981 2904
2982 // Store the value. 2905 // Store the value.
(...skipping 10 matching lines...) Expand all
2993 2916
2994 2917
2995 void FullCodeGenerator::EmitNumberToString(ZoneList<Expression*>* args) { 2918 void FullCodeGenerator::EmitNumberToString(ZoneList<Expression*>* args) {
2996 ASSERT_EQ(args->length(), 1); 2919 ASSERT_EQ(args->length(), 1);
2997 2920
2998 // Load the argument on the stack and call the stub. 2921 // Load the argument on the stack and call the stub.
2999 VisitForStackValue(args->at(0)); 2922 VisitForStackValue(args->at(0));
3000 2923
3001 NumberToStringStub stub; 2924 NumberToStringStub stub;
3002 __ CallStub(&stub); 2925 __ CallStub(&stub);
3003 decrement_stack_height();
3004 context()->Plug(eax); 2926 context()->Plug(eax);
3005 } 2927 }
3006 2928
3007 2929
3008 void FullCodeGenerator::EmitStringCharFromCode(ZoneList<Expression*>* args) { 2930 void FullCodeGenerator::EmitStringCharFromCode(ZoneList<Expression*>* args) {
3009 ASSERT(args->length() == 1); 2931 ASSERT(args->length() == 1);
3010 2932
3011 VisitForAccumulatorValue(args->at(0)); 2933 VisitForAccumulatorValue(args->at(0));
3012 2934
3013 Label done; 2935 Label done;
(...skipping 14 matching lines...) Expand all
3028 2950
3029 VisitForStackValue(args->at(0)); 2951 VisitForStackValue(args->at(0));
3030 VisitForAccumulatorValue(args->at(1)); 2952 VisitForAccumulatorValue(args->at(1));
3031 2953
3032 Register object = ebx; 2954 Register object = ebx;
3033 Register index = eax; 2955 Register index = eax;
3034 Register scratch = ecx; 2956 Register scratch = ecx;
3035 Register result = edx; 2957 Register result = edx;
3036 2958
3037 __ pop(object); 2959 __ pop(object);
3038 decrement_stack_height();
3039 2960
3040 Label need_conversion; 2961 Label need_conversion;
3041 Label index_out_of_range; 2962 Label index_out_of_range;
3042 Label done; 2963 Label done;
3043 StringCharCodeAtGenerator generator(object, 2964 StringCharCodeAtGenerator generator(object,
3044 index, 2965 index,
3045 scratch, 2966 scratch,
3046 result, 2967 result,
3047 &need_conversion, 2968 &need_conversion,
3048 &need_conversion, 2969 &need_conversion,
(...skipping 28 matching lines...) Expand all
3077 VisitForStackValue(args->at(0)); 2998 VisitForStackValue(args->at(0));
3078 VisitForAccumulatorValue(args->at(1)); 2999 VisitForAccumulatorValue(args->at(1));
3079 3000
3080 Register object = ebx; 3001 Register object = ebx;
3081 Register index = eax; 3002 Register index = eax;
3082 Register scratch1 = ecx; 3003 Register scratch1 = ecx;
3083 Register scratch2 = edx; 3004 Register scratch2 = edx;
3084 Register result = eax; 3005 Register result = eax;
3085 3006
3086 __ pop(object); 3007 __ pop(object);
3087 decrement_stack_height();
3088 3008
3089 Label need_conversion; 3009 Label need_conversion;
3090 Label index_out_of_range; 3010 Label index_out_of_range;
3091 Label done; 3011 Label done;
3092 StringCharAtGenerator generator(object, 3012 StringCharAtGenerator generator(object,
3093 index, 3013 index,
3094 scratch1, 3014 scratch1,
3095 scratch2, 3015 scratch2,
3096 result, 3016 result,
3097 &need_conversion, 3017 &need_conversion,
(...skipping 24 matching lines...) Expand all
3122 3042
3123 3043
3124 void FullCodeGenerator::EmitStringAdd(ZoneList<Expression*>* args) { 3044 void FullCodeGenerator::EmitStringAdd(ZoneList<Expression*>* args) {
3125 ASSERT_EQ(2, args->length()); 3045 ASSERT_EQ(2, args->length());
3126 3046
3127 VisitForStackValue(args->at(0)); 3047 VisitForStackValue(args->at(0));
3128 VisitForStackValue(args->at(1)); 3048 VisitForStackValue(args->at(1));
3129 3049
3130 StringAddStub stub(NO_STRING_ADD_FLAGS); 3050 StringAddStub stub(NO_STRING_ADD_FLAGS);
3131 __ CallStub(&stub); 3051 __ CallStub(&stub);
3132 decrement_stack_height(2);
3133 context()->Plug(eax); 3052 context()->Plug(eax);
3134 } 3053 }
3135 3054
3136 3055
3137 void FullCodeGenerator::EmitStringCompare(ZoneList<Expression*>* args) { 3056 void FullCodeGenerator::EmitStringCompare(ZoneList<Expression*>* args) {
3138 ASSERT_EQ(2, args->length()); 3057 ASSERT_EQ(2, args->length());
3139 3058
3140 VisitForStackValue(args->at(0)); 3059 VisitForStackValue(args->at(0));
3141 VisitForStackValue(args->at(1)); 3060 VisitForStackValue(args->at(1));
3142 3061
3143 StringCompareStub stub; 3062 StringCompareStub stub;
3144 __ CallStub(&stub); 3063 __ CallStub(&stub);
3145 decrement_stack_height(2);
3146 context()->Plug(eax); 3064 context()->Plug(eax);
3147 } 3065 }
3148 3066
3149 3067
3150 void FullCodeGenerator::EmitMathSin(ZoneList<Expression*>* args) { 3068 void FullCodeGenerator::EmitMathSin(ZoneList<Expression*>* args) {
3151 // Load the argument on the stack and call the stub. 3069 // Load the argument on the stack and call the stub.
3152 TranscendentalCacheStub stub(TranscendentalCache::SIN, 3070 TranscendentalCacheStub stub(TranscendentalCache::SIN,
3153 TranscendentalCacheStub::TAGGED); 3071 TranscendentalCacheStub::TAGGED);
3154 ASSERT(args->length() == 1); 3072 ASSERT(args->length() == 1);
3155 VisitForStackValue(args->at(0)); 3073 VisitForStackValue(args->at(0));
3156 __ CallStub(&stub); 3074 __ CallStub(&stub);
3157 decrement_stack_height();
3158 context()->Plug(eax); 3075 context()->Plug(eax);
3159 } 3076 }
3160 3077
3161 3078
3162 void FullCodeGenerator::EmitMathCos(ZoneList<Expression*>* args) { 3079 void FullCodeGenerator::EmitMathCos(ZoneList<Expression*>* args) {
3163 // Load the argument on the stack and call the stub. 3080 // Load the argument on the stack and call the stub.
3164 TranscendentalCacheStub stub(TranscendentalCache::COS, 3081 TranscendentalCacheStub stub(TranscendentalCache::COS,
3165 TranscendentalCacheStub::TAGGED); 3082 TranscendentalCacheStub::TAGGED);
3166 ASSERT(args->length() == 1); 3083 ASSERT(args->length() == 1);
3167 VisitForStackValue(args->at(0)); 3084 VisitForStackValue(args->at(0));
3168 __ CallStub(&stub); 3085 __ CallStub(&stub);
3169 decrement_stack_height();
3170 context()->Plug(eax); 3086 context()->Plug(eax);
3171 } 3087 }
3172 3088
3173 3089
3174 void FullCodeGenerator::EmitMathLog(ZoneList<Expression*>* args) { 3090 void FullCodeGenerator::EmitMathLog(ZoneList<Expression*>* args) {
3175 // Load the argument on the stack and call the stub. 3091 // Load the argument on the stack and call the stub.
3176 TranscendentalCacheStub stub(TranscendentalCache::LOG, 3092 TranscendentalCacheStub stub(TranscendentalCache::LOG,
3177 TranscendentalCacheStub::TAGGED); 3093 TranscendentalCacheStub::TAGGED);
3178 ASSERT(args->length() == 1); 3094 ASSERT(args->length() == 1);
3179 VisitForStackValue(args->at(0)); 3095 VisitForStackValue(args->at(0));
3180 __ CallStub(&stub); 3096 __ CallStub(&stub);
3181 decrement_stack_height();
3182 context()->Plug(eax); 3097 context()->Plug(eax);
3183 } 3098 }
3184 3099
3185 3100
3186 void FullCodeGenerator::EmitMathSqrt(ZoneList<Expression*>* args) { 3101 void FullCodeGenerator::EmitMathSqrt(ZoneList<Expression*>* args) {
3187 // Load the argument on the stack and call the runtime function. 3102 // Load the argument on the stack and call the runtime function.
3188 ASSERT(args->length() == 1); 3103 ASSERT(args->length() == 1);
3189 VisitForStackValue(args->at(0)); 3104 VisitForStackValue(args->at(0));
3190 __ CallRuntime(Runtime::kMath_sqrt, 1); 3105 __ CallRuntime(Runtime::kMath_sqrt, 1);
3191 decrement_stack_height();
3192 context()->Plug(eax); 3106 context()->Plug(eax);
3193 } 3107 }
3194 3108
3195 3109
3196 void FullCodeGenerator::EmitCallFunction(ZoneList<Expression*>* args) { 3110 void FullCodeGenerator::EmitCallFunction(ZoneList<Expression*>* args) {
3197 ASSERT(args->length() >= 2); 3111 ASSERT(args->length() >= 2);
3198 3112
3199 int arg_count = args->length() - 2; // 2 ~ receiver and function. 3113 int arg_count = args->length() - 2; // 2 ~ receiver and function.
3200 for (int i = 0; i < arg_count + 1; ++i) { 3114 for (int i = 0; i < arg_count + 1; ++i) {
3201 VisitForStackValue(args->at(i)); 3115 VisitForStackValue(args->at(i));
3202 } 3116 }
3203 VisitForAccumulatorValue(args->last()); // Function. 3117 VisitForAccumulatorValue(args->last()); // Function.
3204 3118
3205 // InvokeFunction requires the function in edi. Move it in there. 3119 // InvokeFunction requires the function in edi. Move it in there.
3206 __ mov(edi, result_register()); 3120 __ mov(edi, result_register());
3207 ParameterCount count(arg_count); 3121 ParameterCount count(arg_count);
3208 __ InvokeFunction(edi, count, CALL_FUNCTION, 3122 __ InvokeFunction(edi, count, CALL_FUNCTION,
3209 NullCallWrapper(), CALL_AS_METHOD); 3123 NullCallWrapper(), CALL_AS_METHOD);
3210 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 3124 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
3211 decrement_stack_height(arg_count + 1);
3212 context()->Plug(eax); 3125 context()->Plug(eax);
3213 } 3126 }
3214 3127
3215 3128
3216 void FullCodeGenerator::EmitRegExpConstructResult(ZoneList<Expression*>* args) { 3129 void FullCodeGenerator::EmitRegExpConstructResult(ZoneList<Expression*>* args) {
3217 // Load the arguments on the stack and call the stub. 3130 // Load the arguments on the stack and call the stub.
3218 RegExpConstructResultStub stub; 3131 RegExpConstructResultStub stub;
3219 ASSERT(args->length() == 3); 3132 ASSERT(args->length() == 3);
3220 VisitForStackValue(args->at(0)); 3133 VisitForStackValue(args->at(0));
3221 VisitForStackValue(args->at(1)); 3134 VisitForStackValue(args->at(1));
3222 VisitForStackValue(args->at(2)); 3135 VisitForStackValue(args->at(2));
3223 __ CallStub(&stub); 3136 __ CallStub(&stub);
3224 decrement_stack_height(3);
3225 context()->Plug(eax); 3137 context()->Plug(eax);
3226 } 3138 }
3227 3139
3228 3140
3229 void FullCodeGenerator::EmitSwapElements(ZoneList<Expression*>* args) { 3141 void FullCodeGenerator::EmitSwapElements(ZoneList<Expression*>* args) {
3230 ASSERT(args->length() == 3); 3142 ASSERT(args->length() == 3);
3231 VisitForStackValue(args->at(0)); 3143 VisitForStackValue(args->at(0));
3232 VisitForStackValue(args->at(1)); 3144 VisitForStackValue(args->at(1));
3233 VisitForStackValue(args->at(2)); 3145 VisitForStackValue(args->at(2));
3234 Label done; 3146 Label done;
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
3307 3219
3308 // We are done. Drop elements from the stack, and return undefined. 3220 // We are done. Drop elements from the stack, and return undefined.
3309 __ add(esp, Immediate(3 * kPointerSize)); 3221 __ add(esp, Immediate(3 * kPointerSize));
3310 __ mov(eax, isolate()->factory()->undefined_value()); 3222 __ mov(eax, isolate()->factory()->undefined_value());
3311 __ jmp(&done); 3223 __ jmp(&done);
3312 3224
3313 __ bind(&slow_case); 3225 __ bind(&slow_case);
3314 __ CallRuntime(Runtime::kSwapElements, 3); 3226 __ CallRuntime(Runtime::kSwapElements, 3);
3315 3227
3316 __ bind(&done); 3228 __ bind(&done);
3317 decrement_stack_height(3);
3318 context()->Plug(eax); 3229 context()->Plug(eax);
3319 } 3230 }
3320 3231
3321 3232
3322 void FullCodeGenerator::EmitGetFromCache(ZoneList<Expression*>* args) { 3233 void FullCodeGenerator::EmitGetFromCache(ZoneList<Expression*>* args) {
3323 ASSERT_EQ(2, args->length()); 3234 ASSERT_EQ(2, args->length());
3324 3235
3325 ASSERT_NE(NULL, args->at(0)->AsLiteral()); 3236 ASSERT_NE(NULL, args->at(0)->AsLiteral());
3326 int cache_id = Smi::cast(*(args->at(0)->AsLiteral()->handle()))->value(); 3237 int cache_id = Smi::cast(*(args->at(0)->AsLiteral()->handle()))->value();
3327 3238
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
3393 __ mov(tmp, FieldOperand(left, JSRegExp::kDataOffset)); 3304 __ mov(tmp, FieldOperand(left, JSRegExp::kDataOffset));
3394 __ cmp(tmp, FieldOperand(right, JSRegExp::kDataOffset)); 3305 __ cmp(tmp, FieldOperand(right, JSRegExp::kDataOffset));
3395 __ j(equal, &ok); 3306 __ j(equal, &ok);
3396 __ bind(&fail); 3307 __ bind(&fail);
3397 __ mov(eax, Immediate(isolate()->factory()->false_value())); 3308 __ mov(eax, Immediate(isolate()->factory()->false_value()));
3398 __ jmp(&done); 3309 __ jmp(&done);
3399 __ bind(&ok); 3310 __ bind(&ok);
3400 __ mov(eax, Immediate(isolate()->factory()->true_value())); 3311 __ mov(eax, Immediate(isolate()->factory()->true_value()));
3401 __ bind(&done); 3312 __ bind(&done);
3402 3313
3403 decrement_stack_height();
3404 context()->Plug(eax); 3314 context()->Plug(eax);
3405 } 3315 }
3406 3316
3407 3317
3408 void FullCodeGenerator::EmitHasCachedArrayIndex(ZoneList<Expression*>* args) { 3318 void FullCodeGenerator::EmitHasCachedArrayIndex(ZoneList<Expression*>* args) {
3409 ASSERT(args->length() == 1); 3319 ASSERT(args->length() == 1);
3410 3320
3411 VisitForAccumulatorValue(args->at(0)); 3321 VisitForAccumulatorValue(args->at(0));
3412 3322
3413 if (FLAG_debug_code) { 3323 if (FLAG_debug_code) {
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after
3697 3607
3698 3608
3699 __ bind(&bailout); 3609 __ bind(&bailout);
3700 __ mov(result_operand, isolate()->factory()->undefined_value()); 3610 __ mov(result_operand, isolate()->factory()->undefined_value());
3701 __ bind(&done); 3611 __ bind(&done);
3702 __ mov(eax, result_operand); 3612 __ mov(eax, result_operand);
3703 // Drop temp values from the stack, and restore context register. 3613 // Drop temp values from the stack, and restore context register.
3704 __ add(esp, Immediate(3 * kPointerSize)); 3614 __ add(esp, Immediate(3 * kPointerSize));
3705 3615
3706 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 3616 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
3707 decrement_stack_height();
3708 context()->Plug(eax); 3617 context()->Plug(eax);
3709 } 3618 }
3710 3619
3711 3620
3712 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { 3621 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
3713 Handle<String> name = expr->name(); 3622 Handle<String> name = expr->name();
3714 if (name->length() > 0 && name->Get(0) == '_') { 3623 if (name->length() > 0 && name->Get(0) == '_') {
3715 Comment cmnt(masm_, "[ InlineRuntimeCall"); 3624 Comment cmnt(masm_, "[ InlineRuntimeCall");
3716 EmitInlineRuntimeCall(expr); 3625 EmitInlineRuntimeCall(expr);
3717 return; 3626 return;
3718 } 3627 }
3719 3628
3720 Comment cmnt(masm_, "[ CallRuntime"); 3629 Comment cmnt(masm_, "[ CallRuntime");
3721 ZoneList<Expression*>* args = expr->arguments(); 3630 ZoneList<Expression*>* args = expr->arguments();
3722 3631
3723 if (expr->is_jsruntime()) { 3632 if (expr->is_jsruntime()) {
3724 // Prepare for calling JS runtime function. 3633 // Prepare for calling JS runtime function.
3725 __ mov(eax, GlobalObjectOperand()); 3634 __ mov(eax, GlobalObjectOperand());
3726 __ push(FieldOperand(eax, GlobalObject::kBuiltinsOffset)); 3635 __ push(FieldOperand(eax, GlobalObject::kBuiltinsOffset));
3727 increment_stack_height();
3728 } 3636 }
3729 3637
3730 // Push the arguments ("left-to-right"). 3638 // Push the arguments ("left-to-right").
3731 int arg_count = args->length(); 3639 int arg_count = args->length();
3732 for (int i = 0; i < arg_count; i++) { 3640 for (int i = 0; i < arg_count; i++) {
3733 VisitForStackValue(args->at(i)); 3641 VisitForStackValue(args->at(i));
3734 } 3642 }
3735 3643
3736 if (expr->is_jsruntime()) { 3644 if (expr->is_jsruntime()) {
3737 // Call the JS runtime function via a call IC. 3645 // Call the JS runtime function via a call IC.
3738 __ Set(ecx, Immediate(expr->name())); 3646 __ Set(ecx, Immediate(expr->name()));
3739 RelocInfo::Mode mode = RelocInfo::CODE_TARGET; 3647 RelocInfo::Mode mode = RelocInfo::CODE_TARGET;
3740 Handle<Code> ic = 3648 Handle<Code> ic =
3741 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); 3649 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode);
3742 __ call(ic, mode, expr->id()); 3650 __ call(ic, mode, expr->id());
3743 // Restore context register. 3651 // Restore context register.
3744 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 3652 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
3745 } else { 3653 } else {
3746 // Call the C runtime function. 3654 // Call the C runtime function.
3747 __ CallRuntime(expr->function(), arg_count); 3655 __ CallRuntime(expr->function(), arg_count);
3748 } 3656 }
3749 decrement_stack_height(arg_count);
3750 if (expr->is_jsruntime()) {
3751 decrement_stack_height();
3752 }
3753
3754 context()->Plug(eax); 3657 context()->Plug(eax);
3755 } 3658 }
3756 3659
3757 3660
3758 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { 3661 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
3759 switch (expr->op()) { 3662 switch (expr->op()) {
3760 case Token::DELETE: { 3663 case Token::DELETE: {
3761 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); 3664 Comment cmnt(masm_, "[ UnaryOperation (DELETE)");
3762 Property* property = expr->expression()->AsProperty(); 3665 Property* property = expr->expression()->AsProperty();
3763 VariableProxy* proxy = expr->expression()->AsVariableProxy(); 3666 VariableProxy* proxy = expr->expression()->AsVariableProxy();
3764 3667
3765 if (property != NULL) { 3668 if (property != NULL) {
3766 VisitForStackValue(property->obj()); 3669 VisitForStackValue(property->obj());
3767 VisitForStackValue(property->key()); 3670 VisitForStackValue(property->key());
3768 __ push(Immediate(Smi::FromInt(strict_mode_flag()))); 3671 __ push(Immediate(Smi::FromInt(strict_mode_flag())));
3769 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); 3672 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
3770 decrement_stack_height(2);
3771 context()->Plug(eax); 3673 context()->Plug(eax);
3772 } else if (proxy != NULL) { 3674 } else if (proxy != NULL) {
3773 Variable* var = proxy->var(); 3675 Variable* var = proxy->var();
3774 // Delete of an unqualified identifier is disallowed in strict mode 3676 // Delete of an unqualified identifier is disallowed in strict mode
3775 // but "delete this" is allowed. 3677 // but "delete this" is allowed.
3776 ASSERT(strict_mode_flag() == kNonStrictMode || var->is_this()); 3678 ASSERT(strict_mode_flag() == kNonStrictMode || var->is_this());
3777 if (var->IsUnallocated()) { 3679 if (var->IsUnallocated()) {
3778 __ push(GlobalObjectOperand()); 3680 __ push(GlobalObjectOperand());
3779 __ push(Immediate(var->name())); 3681 __ push(Immediate(var->name()));
3780 __ push(Immediate(Smi::FromInt(kNonStrictMode))); 3682 __ push(Immediate(Smi::FromInt(kNonStrictMode)));
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
3830 } 3732 }
3831 break; 3733 break;
3832 } 3734 }
3833 3735
3834 case Token::TYPEOF: { 3736 case Token::TYPEOF: {
3835 Comment cmnt(masm_, "[ UnaryOperation (TYPEOF)"); 3737 Comment cmnt(masm_, "[ UnaryOperation (TYPEOF)");
3836 { StackValueContext context(this); 3738 { StackValueContext context(this);
3837 VisitForTypeofValue(expr->expression()); 3739 VisitForTypeofValue(expr->expression());
3838 } 3740 }
3839 __ CallRuntime(Runtime::kTypeof, 1); 3741 __ CallRuntime(Runtime::kTypeof, 1);
3840 decrement_stack_height();
3841 context()->Plug(eax); 3742 context()->Plug(eax);
3842 break; 3743 break;
3843 } 3744 }
3844 3745
3845 case Token::ADD: { 3746 case Token::ADD: {
3846 Comment cmt(masm_, "[ UnaryOperation (ADD)"); 3747 Comment cmt(masm_, "[ UnaryOperation (ADD)");
3847 VisitForAccumulatorValue(expr->expression()); 3748 VisitForAccumulatorValue(expr->expression());
3848 Label no_conversion; 3749 Label no_conversion;
3849 __ JumpIfSmi(result_register(), &no_conversion); 3750 __ JumpIfSmi(result_register(), &no_conversion);
3850 ToNumberStub convert_stub; 3751 ToNumberStub convert_stub;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
3884 } 3785 }
3885 3786
3886 3787
3887 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { 3788 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
3888 Comment cmnt(masm_, "[ CountOperation"); 3789 Comment cmnt(masm_, "[ CountOperation");
3889 SetSourcePosition(expr->position()); 3790 SetSourcePosition(expr->position());
3890 3791
3891 // Invalid left-hand sides are rewritten to have a 'throw ReferenceError' 3792 // Invalid left-hand sides are rewritten to have a 'throw ReferenceError'
3892 // as the left-hand side. 3793 // as the left-hand side.
3893 if (!expr->expression()->IsValidLeftHandSide()) { 3794 if (!expr->expression()->IsValidLeftHandSide()) {
3894 ASSERT(expr->expression()->AsThrow() != NULL); 3795 VisitForEffect(expr->expression());
3895 VisitInCurrentContext(expr->expression());
3896 // Visiting Throw does not plug the context.
3897 context()->Plug(eax);
3898 return; 3796 return;
3899 } 3797 }
3900 3798
3901 // Expression can only be a property, a global or a (parameter or local) 3799 // Expression can only be a property, a global or a (parameter or local)
3902 // slot. 3800 // slot.
3903 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; 3801 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
3904 LhsKind assign_type = VARIABLE; 3802 LhsKind assign_type = VARIABLE;
3905 Property* prop = expr->expression()->AsProperty(); 3803 Property* prop = expr->expression()->AsProperty();
3906 // In case of a property we use the uninitialized expression context 3804 // In case of a property we use the uninitialized expression context
3907 // of the key to detect a named property. 3805 // of the key to detect a named property.
3908 if (prop != NULL) { 3806 if (prop != NULL) {
3909 assign_type = 3807 assign_type =
3910 (prop->key()->IsPropertyName()) ? NAMED_PROPERTY : KEYED_PROPERTY; 3808 (prop->key()->IsPropertyName()) ? NAMED_PROPERTY : KEYED_PROPERTY;
3911 } 3809 }
3912 3810
3913 // Evaluate expression and get value. 3811 // Evaluate expression and get value.
3914 if (assign_type == VARIABLE) { 3812 if (assign_type == VARIABLE) {
3915 ASSERT(expr->expression()->AsVariableProxy()->var() != NULL); 3813 ASSERT(expr->expression()->AsVariableProxy()->var() != NULL);
3916 AccumulatorValueContext context(this); 3814 AccumulatorValueContext context(this);
3917 EmitVariableLoad(expr->expression()->AsVariableProxy()); 3815 EmitVariableLoad(expr->expression()->AsVariableProxy());
3918 } else { 3816 } else {
3919 // Reserve space for result of postfix operation. 3817 // Reserve space for result of postfix operation.
3920 if (expr->is_postfix() && !context()->IsEffect()) { 3818 if (expr->is_postfix() && !context()->IsEffect()) {
3921 __ push(Immediate(Smi::FromInt(0))); 3819 __ push(Immediate(Smi::FromInt(0)));
3922 increment_stack_height();
3923 } 3820 }
3924 if (assign_type == NAMED_PROPERTY) { 3821 if (assign_type == NAMED_PROPERTY) {
3925 // Put the object both on the stack and in the accumulator. 3822 // Put the object both on the stack and in the accumulator.
3926 VisitForAccumulatorValue(prop->obj()); 3823 VisitForAccumulatorValue(prop->obj());
3927 __ push(eax); 3824 __ push(eax);
3928 increment_stack_height();
3929 EmitNamedPropertyLoad(prop); 3825 EmitNamedPropertyLoad(prop);
3930 } else { 3826 } else {
3931 VisitForStackValue(prop->obj()); 3827 VisitForStackValue(prop->obj());
3932 VisitForAccumulatorValue(prop->key()); 3828 VisitForAccumulatorValue(prop->key());
3933 __ mov(edx, Operand(esp, 0)); 3829 __ mov(edx, Operand(esp, 0));
3934 __ push(eax); 3830 __ push(eax);
3935 increment_stack_height();
3936 EmitKeyedPropertyLoad(prop); 3831 EmitKeyedPropertyLoad(prop);
3937 } 3832 }
3938 } 3833 }
3939 3834
3940 // We need a second deoptimization point after loading the value 3835 // We need a second deoptimization point after loading the value
3941 // in case evaluating the property load my have a side effect. 3836 // in case evaluating the property load my have a side effect.
3942 if (assign_type == VARIABLE) { 3837 if (assign_type == VARIABLE) {
3943 PrepareForBailout(expr->expression(), TOS_REG); 3838 PrepareForBailout(expr->expression(), TOS_REG);
3944 } else { 3839 } else {
3945 PrepareForBailoutForId(expr->CountId(), TOS_REG); 3840 PrepareForBailoutForId(expr->CountId(), TOS_REG);
(...skipping 10 matching lines...) Expand all
3956 3851
3957 // Save result for postfix expressions. 3852 // Save result for postfix expressions.
3958 if (expr->is_postfix()) { 3853 if (expr->is_postfix()) {
3959 if (!context()->IsEffect()) { 3854 if (!context()->IsEffect()) {
3960 // Save the result on the stack. If we have a named or keyed property 3855 // Save the result on the stack. If we have a named or keyed property
3961 // we store the result under the receiver that is currently on top 3856 // we store the result under the receiver that is currently on top
3962 // of the stack. 3857 // of the stack.
3963 switch (assign_type) { 3858 switch (assign_type) {
3964 case VARIABLE: 3859 case VARIABLE:
3965 __ push(eax); 3860 __ push(eax);
3966 increment_stack_height();
3967 break; 3861 break;
3968 case NAMED_PROPERTY: 3862 case NAMED_PROPERTY:
3969 __ mov(Operand(esp, kPointerSize), eax); 3863 __ mov(Operand(esp, kPointerSize), eax);
3970 break; 3864 break;
3971 case KEYED_PROPERTY: 3865 case KEYED_PROPERTY:
3972 __ mov(Operand(esp, 2 * kPointerSize), eax); 3866 __ mov(Operand(esp, 2 * kPointerSize), eax);
3973 break; 3867 break;
3974 } 3868 }
3975 } 3869 }
3976 } 3870 }
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
4030 // Perform the assignment as if via '='. 3924 // Perform the assignment as if via '='.
4031 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 3925 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
4032 Token::ASSIGN); 3926 Token::ASSIGN);
4033 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3927 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4034 context()->Plug(eax); 3928 context()->Plug(eax);
4035 } 3929 }
4036 break; 3930 break;
4037 case NAMED_PROPERTY: { 3931 case NAMED_PROPERTY: {
4038 __ mov(ecx, prop->key()->AsLiteral()->handle()); 3932 __ mov(ecx, prop->key()->AsLiteral()->handle());
4039 __ pop(edx); 3933 __ pop(edx);
4040 decrement_stack_height();
4041 Handle<Code> ic = is_strict_mode() 3934 Handle<Code> ic = is_strict_mode()
4042 ? isolate()->builtins()->StoreIC_Initialize_Strict() 3935 ? isolate()->builtins()->StoreIC_Initialize_Strict()
4043 : isolate()->builtins()->StoreIC_Initialize(); 3936 : isolate()->builtins()->StoreIC_Initialize();
4044 __ call(ic, RelocInfo::CODE_TARGET, expr->id()); 3937 __ call(ic, RelocInfo::CODE_TARGET, expr->id());
4045 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3938 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4046 if (expr->is_postfix()) { 3939 if (expr->is_postfix()) {
4047 if (!context()->IsEffect()) { 3940 if (!context()->IsEffect()) {
4048 context()->PlugTOS(); 3941 context()->PlugTOS();
4049 } 3942 }
4050 } else { 3943 } else {
4051 context()->Plug(eax); 3944 context()->Plug(eax);
4052 } 3945 }
4053 break; 3946 break;
4054 } 3947 }
4055 case KEYED_PROPERTY: { 3948 case KEYED_PROPERTY: {
4056 __ pop(ecx); 3949 __ pop(ecx);
4057 __ pop(edx); 3950 __ pop(edx);
4058 decrement_stack_height();
4059 decrement_stack_height();
4060 Handle<Code> ic = is_strict_mode() 3951 Handle<Code> ic = is_strict_mode()
4061 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 3952 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
4062 : isolate()->builtins()->KeyedStoreIC_Initialize(); 3953 : isolate()->builtins()->KeyedStoreIC_Initialize();
4063 __ call(ic, RelocInfo::CODE_TARGET, expr->id()); 3954 __ call(ic, RelocInfo::CODE_TARGET, expr->id());
4064 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3955 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4065 if (expr->is_postfix()) { 3956 if (expr->is_postfix()) {
4066 // Result is on the stack 3957 // Result is on the stack
4067 if (!context()->IsEffect()) { 3958 if (!context()->IsEffect()) {
4068 context()->PlugTOS(); 3959 context()->PlugTOS();
4069 } 3960 }
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
4202 Label* fall_through = NULL; 4093 Label* fall_through = NULL;
4203 context()->PrepareTest(&materialize_true, &materialize_false, 4094 context()->PrepareTest(&materialize_true, &materialize_false,
4204 &if_true, &if_false, &fall_through); 4095 &if_true, &if_false, &fall_through);
4205 4096
4206 Token::Value op = expr->op(); 4097 Token::Value op = expr->op();
4207 VisitForStackValue(expr->left()); 4098 VisitForStackValue(expr->left());
4208 switch (op) { 4099 switch (op) {
4209 case Token::IN: 4100 case Token::IN:
4210 VisitForStackValue(expr->right()); 4101 VisitForStackValue(expr->right());
4211 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION); 4102 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION);
4212 decrement_stack_height(2);
4213 PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL); 4103 PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL);
4214 __ cmp(eax, isolate()->factory()->true_value()); 4104 __ cmp(eax, isolate()->factory()->true_value());
4215 Split(equal, if_true, if_false, fall_through); 4105 Split(equal, if_true, if_false, fall_through);
4216 break; 4106 break;
4217 4107
4218 case Token::INSTANCEOF: { 4108 case Token::INSTANCEOF: {
4219 VisitForStackValue(expr->right()); 4109 VisitForStackValue(expr->right());
4220 InstanceofStub stub(InstanceofStub::kNoFlags); 4110 InstanceofStub stub(InstanceofStub::kNoFlags);
4221 __ CallStub(&stub); 4111 __ CallStub(&stub);
4222 decrement_stack_height(2);
4223 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); 4112 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
4224 __ test(eax, eax); 4113 __ test(eax, eax);
4225 // The stub returns 0 for true. 4114 // The stub returns 0 for true.
4226 Split(zero, if_true, if_false, fall_through); 4115 Split(zero, if_true, if_false, fall_through);
4227 break; 4116 break;
4228 } 4117 }
4229 4118
4230 default: { 4119 default: {
4231 VisitForAccumulatorValue(expr->right()); 4120 VisitForAccumulatorValue(expr->right());
4232 Condition cc = no_condition; 4121 Condition cc = no_condition;
(...skipping 13 matching lines...) Expand all
4246 break; 4135 break;
4247 case Token::GTE: 4136 case Token::GTE:
4248 cc = greater_equal; 4137 cc = greater_equal;
4249 break; 4138 break;
4250 case Token::IN: 4139 case Token::IN:
4251 case Token::INSTANCEOF: 4140 case Token::INSTANCEOF:
4252 default: 4141 default:
4253 UNREACHABLE(); 4142 UNREACHABLE();
4254 } 4143 }
4255 __ pop(edx); 4144 __ pop(edx);
4256 decrement_stack_height();
4257 4145
4258 bool inline_smi_code = ShouldInlineSmiCase(op); 4146 bool inline_smi_code = ShouldInlineSmiCase(op);
4259 JumpPatchSite patch_site(masm_); 4147 JumpPatchSite patch_site(masm_);
4260 if (inline_smi_code) { 4148 if (inline_smi_code) {
4261 Label slow_case; 4149 Label slow_case;
4262 __ mov(ecx, edx); 4150 __ mov(ecx, edx);
4263 __ or_(ecx, eax); 4151 __ or_(ecx, eax);
4264 patch_site.EmitJumpIfNotSmi(ecx, &slow_case, Label::kNear); 4152 patch_site.EmitJumpIfNotSmi(ecx, &slow_case, Label::kNear);
4265 __ cmp(edx, eax); 4153 __ cmp(edx, eax);
4266 Split(cc, if_true, if_false, NULL); 4154 Split(cc, if_true, if_false, NULL);
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
4422 *context_length = 0; 4310 *context_length = 0;
4423 return previous_; 4311 return previous_;
4424 } 4312 }
4425 4313
4426 4314
4427 #undef __ 4315 #undef __
4428 4316
4429 } } // namespace v8::internal 4317 } } // namespace v8::internal
4430 4318
4431 #endif // V8_TARGET_ARCH_IA32 4319 #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