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

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

Issue 6880010: Merge (7265, 7271] from bleeding_edge to experimental/gc branch.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: '' Created 9 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
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 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 #endif 122 #endif
123 123
124 __ push(ebp); // Caller's frame pointer. 124 __ push(ebp); // Caller's frame pointer.
125 __ mov(ebp, esp); 125 __ mov(ebp, esp);
126 __ push(esi); // Callee's context. 126 __ push(esi); // Callee's context.
127 __ push(edi); // Callee's JS Function. 127 __ push(edi); // Callee's JS Function.
128 128
129 { Comment cmnt(masm_, "[ Allocate locals"); 129 { Comment cmnt(masm_, "[ Allocate locals");
130 int locals_count = scope()->num_stack_slots(); 130 int locals_count = scope()->num_stack_slots();
131 if (locals_count == 1) { 131 if (locals_count == 1) {
132 __ push(Immediate(Factory::undefined_value())); 132 __ push(Immediate(isolate()->factory()->undefined_value()));
133 } else if (locals_count > 1) { 133 } else if (locals_count > 1) {
134 __ mov(eax, Immediate(Factory::undefined_value())); 134 __ mov(eax, Immediate(isolate()->factory()->undefined_value()));
135 for (int i = 0; i < locals_count; i++) { 135 for (int i = 0; i < locals_count; i++) {
136 __ push(eax); 136 __ push(eax);
137 } 137 }
138 } 138 }
139 } 139 }
140 140
141 bool function_in_register = true; 141 bool function_in_register = true;
142 142
143 // Possibly allocate a local context. 143 // Possibly allocate a local context.
144 int heap_slots = scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; 144 int heap_slots = scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
245 { Comment cmnt(masm_, "[ Body"); 245 { Comment cmnt(masm_, "[ Body");
246 ASSERT(loop_depth() == 0); 246 ASSERT(loop_depth() == 0);
247 VisitStatements(function()->body()); 247 VisitStatements(function()->body());
248 ASSERT(loop_depth() == 0); 248 ASSERT(loop_depth() == 0);
249 } 249 }
250 } 250 }
251 251
252 // Always emit a 'return undefined' in case control fell off the end of 252 // Always emit a 'return undefined' in case control fell off the end of
253 // the body. 253 // the body.
254 { Comment cmnt(masm_, "[ return <undefined>;"); 254 { Comment cmnt(masm_, "[ return <undefined>;");
255 __ mov(eax, Factory::undefined_value()); 255 __ mov(eax, isolate()->factory()->undefined_value());
256 EmitReturnSequence(); 256 EmitReturnSequence();
257 } 257 }
258 } 258 }
259 259
260 260
261 void FullCodeGenerator::ClearAccumulator() { 261 void FullCodeGenerator::ClearAccumulator() {
262 __ Set(eax, Immediate(Smi::FromInt(0))); 262 __ Set(eax, Immediate(Smi::FromInt(0)));
263 } 263 }
264 264
265 265
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
460 ASSERT(materialize_true == materialize_false); 460 ASSERT(materialize_true == materialize_false);
461 __ bind(materialize_true); 461 __ bind(materialize_true);
462 } 462 }
463 463
464 464
465 void FullCodeGenerator::AccumulatorValueContext::Plug( 465 void FullCodeGenerator::AccumulatorValueContext::Plug(
466 Label* materialize_true, 466 Label* materialize_true,
467 Label* materialize_false) const { 467 Label* materialize_false) const {
468 NearLabel done; 468 NearLabel done;
469 __ bind(materialize_true); 469 __ bind(materialize_true);
470 __ mov(result_register(), Factory::true_value()); 470 __ mov(result_register(), isolate()->factory()->true_value());
471 __ jmp(&done); 471 __ jmp(&done);
472 __ bind(materialize_false); 472 __ bind(materialize_false);
473 __ mov(result_register(), Factory::false_value()); 473 __ mov(result_register(), isolate()->factory()->false_value());
474 __ bind(&done); 474 __ bind(&done);
475 } 475 }
476 476
477 477
478 void FullCodeGenerator::StackValueContext::Plug( 478 void FullCodeGenerator::StackValueContext::Plug(
479 Label* materialize_true, 479 Label* materialize_true,
480 Label* materialize_false) const { 480 Label* materialize_false) const {
481 NearLabel done; 481 NearLabel done;
482 __ bind(materialize_true); 482 __ bind(materialize_true);
483 __ push(Immediate(Factory::true_value())); 483 __ push(Immediate(isolate()->factory()->true_value()));
484 __ jmp(&done); 484 __ jmp(&done);
485 __ bind(materialize_false); 485 __ bind(materialize_false);
486 __ push(Immediate(Factory::false_value())); 486 __ push(Immediate(isolate()->factory()->false_value()));
487 __ bind(&done); 487 __ bind(&done);
488 } 488 }
489 489
490 490
491 void FullCodeGenerator::TestContext::Plug(Label* materialize_true, 491 void FullCodeGenerator::TestContext::Plug(Label* materialize_true,
492 Label* materialize_false) const { 492 Label* materialize_false) const {
493 ASSERT(materialize_true == true_label_); 493 ASSERT(materialize_true == true_label_);
494 ASSERT(materialize_false == false_label_); 494 ASSERT(materialize_false == false_label_);
495 } 495 }
496 496
497 497
498 void FullCodeGenerator::EffectContext::Plug(bool flag) const { 498 void FullCodeGenerator::EffectContext::Plug(bool flag) const {
499 } 499 }
500 500
501 501
502 void FullCodeGenerator::AccumulatorValueContext::Plug(bool flag) const { 502 void FullCodeGenerator::AccumulatorValueContext::Plug(bool flag) const {
503 Handle<Object> value = 503 Handle<Object> value = flag
504 flag ? Factory::true_value() : Factory::false_value(); 504 ? isolate()->factory()->true_value()
505 : isolate()->factory()->false_value();
505 __ mov(result_register(), value); 506 __ mov(result_register(), value);
506 } 507 }
507 508
508 509
509 void FullCodeGenerator::StackValueContext::Plug(bool flag) const { 510 void FullCodeGenerator::StackValueContext::Plug(bool flag) const {
510 Handle<Object> value = 511 Handle<Object> value = flag
511 flag ? Factory::true_value() : Factory::false_value(); 512 ? isolate()->factory()->true_value()
513 : isolate()->factory()->false_value();
512 __ push(Immediate(value)); 514 __ push(Immediate(value));
513 } 515 }
514 516
515 517
516 void FullCodeGenerator::TestContext::Plug(bool flag) const { 518 void FullCodeGenerator::TestContext::Plug(bool flag) const {
517 codegen()->PrepareForBailoutBeforeSplit(TOS_REG, 519 codegen()->PrepareForBailoutBeforeSplit(TOS_REG,
518 true, 520 true,
519 true_label_, 521 true_label_,
520 false_label_); 522 false_label_);
521 if (flag) { 523 if (flag) {
522 if (true_label_ != fall_through_) __ jmp(true_label_); 524 if (true_label_ != fall_through_) __ jmp(true_label_);
523 } else { 525 } else {
524 if (false_label_ != fall_through_) __ jmp(false_label_); 526 if (false_label_ != fall_through_) __ jmp(false_label_);
525 } 527 }
526 } 528 }
527 529
528 530
529 void FullCodeGenerator::DoTest(Label* if_true, 531 void FullCodeGenerator::DoTest(Label* if_true,
530 Label* if_false, 532 Label* if_false,
531 Label* fall_through) { 533 Label* fall_through) {
532 // Emit the inlined tests assumed by the stub. 534 // Emit the inlined tests assumed by the stub.
533 __ cmp(result_register(), Factory::undefined_value()); 535 __ cmp(result_register(), isolate()->factory()->undefined_value());
534 __ j(equal, if_false); 536 __ j(equal, if_false);
535 __ cmp(result_register(), Factory::true_value()); 537 __ cmp(result_register(), isolate()->factory()->true_value());
536 __ j(equal, if_true); 538 __ j(equal, if_true);
537 __ cmp(result_register(), Factory::false_value()); 539 __ cmp(result_register(), isolate()->factory()->false_value());
538 __ j(equal, if_false); 540 __ j(equal, if_false);
539 STATIC_ASSERT(kSmiTag == 0); 541 STATIC_ASSERT(kSmiTag == 0);
540 __ test(result_register(), Operand(result_register())); 542 __ test(result_register(), Operand(result_register()));
541 __ j(zero, if_false); 543 __ j(zero, if_false);
542 __ test(result_register(), Immediate(kSmiTagMask)); 544 __ test(result_register(), Immediate(kSmiTagMask));
543 __ j(zero, if_true); 545 __ j(zero, if_true);
544 546
545 // Call the ToBoolean stub for all other cases. 547 // Call the ToBoolean stub for all other cases.
546 ToBooleanStub stub; 548 ToBooleanStub stub;
547 __ push(result_register()); 549 __ push(result_register());
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
623 NearLabel skip; 625 NearLabel skip;
624 if (should_normalize) __ jmp(&skip); 626 if (should_normalize) __ jmp(&skip);
625 627
626 ForwardBailoutStack* current = forward_bailout_stack_; 628 ForwardBailoutStack* current = forward_bailout_stack_;
627 while (current != NULL) { 629 while (current != NULL) {
628 PrepareForBailout(current->expr(), state); 630 PrepareForBailout(current->expr(), state);
629 current = current->parent(); 631 current = current->parent();
630 } 632 }
631 633
632 if (should_normalize) { 634 if (should_normalize) {
633 __ cmp(eax, Factory::true_value()); 635 __ cmp(eax, isolate()->factory()->true_value());
634 Split(equal, if_true, if_false, NULL); 636 Split(equal, if_true, if_false, NULL);
635 __ bind(&skip); 637 __ bind(&skip);
636 } 638 }
637 } 639 }
638 640
639 641
640 void FullCodeGenerator::EmitDeclaration(Variable* variable, 642 void FullCodeGenerator::EmitDeclaration(Variable* variable,
641 Variable::Mode mode, 643 Variable::Mode mode,
642 FunctionLiteral* function) { 644 FunctionLiteral* function) {
643 Comment cmnt(masm_, "[ Declaration"); 645 Comment cmnt(masm_, "[ Declaration");
644 ASSERT(variable != NULL); // Must have been resolved. 646 ASSERT(variable != NULL); // Must have been resolved.
645 Slot* slot = variable->AsSlot(); 647 Slot* slot = variable->AsSlot();
646 Property* prop = variable->AsProperty(); 648 Property* prop = variable->AsProperty();
647 649
648 if (slot != NULL) { 650 if (slot != NULL) {
649 switch (slot->type()) { 651 switch (slot->type()) {
650 case Slot::PARAMETER: 652 case Slot::PARAMETER:
651 case Slot::LOCAL: 653 case Slot::LOCAL:
652 if (mode == Variable::CONST) { 654 if (mode == Variable::CONST) {
653 __ mov(Operand(ebp, SlotOffset(slot)), 655 __ mov(Operand(ebp, SlotOffset(slot)),
654 Immediate(Factory::the_hole_value())); 656 Immediate(isolate()->factory()->the_hole_value()));
655 } else if (function != NULL) { 657 } else if (function != NULL) {
656 VisitForAccumulatorValue(function); 658 VisitForAccumulatorValue(function);
657 __ mov(Operand(ebp, SlotOffset(slot)), result_register()); 659 __ mov(Operand(ebp, SlotOffset(slot)), result_register());
658 } 660 }
659 break; 661 break;
660 662
661 case Slot::CONTEXT: 663 case Slot::CONTEXT:
662 // We bypass the general EmitSlotSearch because we know more about 664 // We bypass the general EmitSlotSearch because we know more about
663 // this specific context. 665 // this specific context.
664 666
665 // The variable in the decl always resides in the current function 667 // The variable in the decl always resides in the current function
666 // context. 668 // context.
667 ASSERT_EQ(0, scope()->ContextChainLength(variable->scope())); 669 ASSERT_EQ(0, scope()->ContextChainLength(variable->scope()));
668 if (FLAG_debug_code) { 670 if (FLAG_debug_code) {
669 // Check that we're not inside a 'with'. 671 // Check that we're not inside a 'with'.
670 __ mov(ebx, ContextOperand(esi, Context::FCONTEXT_INDEX)); 672 __ mov(ebx, ContextOperand(esi, Context::FCONTEXT_INDEX));
671 __ cmp(ebx, Operand(esi)); 673 __ cmp(ebx, Operand(esi));
672 __ Check(equal, "Unexpected declaration in current context."); 674 __ Check(equal, "Unexpected declaration in current context.");
673 } 675 }
674 if (mode == Variable::CONST) { 676 if (mode == Variable::CONST) {
675 __ mov(ContextOperand(esi, slot->index()), 677 __ mov(ContextOperand(esi, slot->index()),
676 Immediate(Factory::the_hole_value())); 678 Immediate(isolate()->factory()->the_hole_value()));
677 // No write barrier since the hole value is in old space. 679 // No write barrier since the hole value is in old space.
678 } else if (function != NULL) { 680 } else if (function != NULL) {
679 VisitForAccumulatorValue(function); 681 VisitForAccumulatorValue(function);
680 __ mov(ContextOperand(esi, slot->index()), result_register()); 682 __ mov(ContextOperand(esi, slot->index()), result_register());
681 int offset = Context::SlotOffset(slot->index()); 683 int offset = Context::SlotOffset(slot->index());
682 __ mov(ebx, esi); 684 __ mov(ebx, esi);
683 __ RecordWrite(ebx, offset, result_register(), ecx, kDontSaveFPRegs); 685 __ RecordWrite(ebx, offset, result_register(), ecx, kDontSaveFPRegs);
684 } 686 }
685 break; 687 break;
686 688
687 case Slot::LOOKUP: { 689 case Slot::LOOKUP: {
688 __ push(esi); 690 __ push(esi);
689 __ push(Immediate(variable->name())); 691 __ push(Immediate(variable->name()));
690 // Declaration nodes are always introduced in one of two modes. 692 // Declaration nodes are always introduced in one of two modes.
691 ASSERT(mode == Variable::VAR || mode == Variable::CONST); 693 ASSERT(mode == Variable::VAR || mode == Variable::CONST);
692 PropertyAttributes attr = (mode == Variable::VAR) ? NONE : READ_ONLY; 694 PropertyAttributes attr = (mode == Variable::VAR) ? NONE : READ_ONLY;
693 __ push(Immediate(Smi::FromInt(attr))); 695 __ push(Immediate(Smi::FromInt(attr)));
694 // Push initial value, if any. 696 // Push initial value, if any.
695 // Note: For variables we must not push an initial value (such as 697 // Note: For variables we must not push an initial value (such as
696 // 'undefined') because we may have a (legal) redeclaration and we 698 // 'undefined') because we may have a (legal) redeclaration and we
697 // must not destroy the current value. 699 // must not destroy the current value.
698 if (mode == Variable::CONST) { 700 if (mode == Variable::CONST) {
699 __ push(Immediate(Factory::the_hole_value())); 701 __ push(Immediate(isolate()->factory()->the_hole_value()));
700 } else if (function != NULL) { 702 } else if (function != NULL) {
701 VisitForStackValue(function); 703 VisitForStackValue(function);
702 } else { 704 } else {
703 __ push(Immediate(Smi::FromInt(0))); // No initial value! 705 __ push(Immediate(Smi::FromInt(0))); // No initial value!
704 } 706 }
705 __ CallRuntime(Runtime::kDeclareContextSlot, 4); 707 __ CallRuntime(Runtime::kDeclareContextSlot, 4);
706 break; 708 break;
707 } 709 }
708 } 710 }
709 711
710 } else if (prop != NULL) { 712 } else if (prop != NULL) {
711 if (function != NULL || mode == Variable::CONST) { 713 if (function != NULL || mode == Variable::CONST) {
712 // We are declaring a function or constant that rewrites to a 714 // We are declaring a function or constant that rewrites to a
713 // property. Use (keyed) IC to set the initial value. We cannot 715 // property. Use (keyed) IC to set the initial value. We cannot
714 // visit the rewrite because it's shared and we risk recording 716 // visit the rewrite because it's shared and we risk recording
715 // duplicate AST IDs for bailouts from optimized code. 717 // duplicate AST IDs for bailouts from optimized code.
716 ASSERT(prop->obj()->AsVariableProxy() != NULL); 718 ASSERT(prop->obj()->AsVariableProxy() != NULL);
717 { AccumulatorValueContext for_object(this); 719 { AccumulatorValueContext for_object(this);
718 EmitVariableLoad(prop->obj()->AsVariableProxy()->var()); 720 EmitVariableLoad(prop->obj()->AsVariableProxy()->var());
719 } 721 }
720 722
721 if (function != NULL) { 723 if (function != NULL) {
722 __ push(eax); 724 __ push(eax);
723 VisitForAccumulatorValue(function); 725 VisitForAccumulatorValue(function);
724 __ pop(edx); 726 __ pop(edx);
725 } else { 727 } else {
726 __ mov(edx, eax); 728 __ mov(edx, eax);
727 __ mov(eax, Factory::the_hole_value()); 729 __ mov(eax, isolate()->factory()->the_hole_value());
728 } 730 }
729 ASSERT(prop->key()->AsLiteral() != NULL && 731 ASSERT(prop->key()->AsLiteral() != NULL &&
730 prop->key()->AsLiteral()->handle()->IsSmi()); 732 prop->key()->AsLiteral()->handle()->IsSmi());
731 __ Set(ecx, Immediate(prop->key()->AsLiteral()->handle())); 733 __ Set(ecx, Immediate(prop->key()->AsLiteral()->handle()));
732 734
733 Handle<Code> ic(Builtins::builtin( 735 Handle<Code> ic(isolate()->builtins()->builtin(is_strict_mode()
734 is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict 736 ? Builtins::KeyedStoreIC_Initialize_Strict
735 : Builtins::KeyedStoreIC_Initialize)); 737 : Builtins::KeyedStoreIC_Initialize));
736 EmitCallIC(ic, RelocInfo::CODE_TARGET); 738 EmitCallIC(ic, RelocInfo::CODE_TARGET);
737 } 739 }
738 } 740 }
739 } 741 }
740 742
741 743
742 void FullCodeGenerator::VisitDeclaration(Declaration* decl) { 744 void FullCodeGenerator::VisitDeclaration(Declaration* decl) {
743 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun()); 745 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun());
744 } 746 }
745 747
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
842 SetStatementPosition(stmt); 844 SetStatementPosition(stmt);
843 845
844 Label loop, exit; 846 Label loop, exit;
845 ForIn loop_statement(this, stmt); 847 ForIn loop_statement(this, stmt);
846 increment_loop_depth(); 848 increment_loop_depth();
847 849
848 // Get the object to enumerate over. Both SpiderMonkey and JSC 850 // Get the object to enumerate over. Both SpiderMonkey and JSC
849 // ignore null and undefined in contrast to the specification; see 851 // ignore null and undefined in contrast to the specification; see
850 // ECMA-262 section 12.6.4. 852 // ECMA-262 section 12.6.4.
851 VisitForAccumulatorValue(stmt->enumerable()); 853 VisitForAccumulatorValue(stmt->enumerable());
852 __ cmp(eax, Factory::undefined_value()); 854 __ cmp(eax, isolate()->factory()->undefined_value());
853 __ j(equal, &exit); 855 __ j(equal, &exit);
854 __ cmp(eax, Factory::null_value()); 856 __ cmp(eax, isolate()->factory()->null_value());
855 __ j(equal, &exit); 857 __ j(equal, &exit);
856 858
857 // Convert the object to a JS object. 859 // Convert the object to a JS object.
858 NearLabel convert, done_convert; 860 NearLabel convert, done_convert;
859 __ test(eax, Immediate(kSmiTagMask)); 861 __ test(eax, Immediate(kSmiTagMask));
860 __ j(zero, &convert); 862 __ j(zero, &convert);
861 __ CmpObjectType(eax, FIRST_JS_OBJECT_TYPE, ecx); 863 __ CmpObjectType(eax, FIRST_JS_OBJECT_TYPE, ecx);
862 __ j(above_equal, &done_convert); 864 __ j(above_equal, &done_convert);
863 __ bind(&convert); 865 __ bind(&convert);
864 __ push(eax); 866 __ push(eax);
865 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION); 867 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
866 __ bind(&done_convert); 868 __ bind(&done_convert);
867 __ push(eax); 869 __ push(eax);
868 870
869 // Check cache validity in generated code. This is a fast case for 871 // Check cache validity in generated code. This is a fast case for
870 // the JSObject::IsSimpleEnum cache validity checks. If we cannot 872 // the JSObject::IsSimpleEnum cache validity checks. If we cannot
871 // guarantee cache validity, call the runtime system to check cache 873 // guarantee cache validity, call the runtime system to check cache
872 // validity or get the property names in a fixed array. 874 // validity or get the property names in a fixed array.
873 Label next, call_runtime; 875 Label next, call_runtime;
874 __ mov(ecx, eax); 876 __ mov(ecx, eax);
875 __ bind(&next); 877 __ bind(&next);
876 878
877 // Check that there are no elements. Register ecx contains the 879 // Check that there are no elements. Register ecx contains the
878 // current JS object we've reached through the prototype chain. 880 // current JS object we've reached through the prototype chain.
879 __ cmp(FieldOperand(ecx, JSObject::kElementsOffset), 881 __ cmp(FieldOperand(ecx, JSObject::kElementsOffset),
880 Factory::empty_fixed_array()); 882 isolate()->factory()->empty_fixed_array());
881 __ j(not_equal, &call_runtime); 883 __ j(not_equal, &call_runtime);
882 884
883 // Check that instance descriptors are not empty so that we can 885 // Check that instance descriptors are not empty so that we can
884 // check for an enum cache. Leave the map in ebx for the subsequent 886 // check for an enum cache. Leave the map in ebx for the subsequent
885 // prototype load. 887 // prototype load.
886 __ mov(ebx, FieldOperand(ecx, HeapObject::kMapOffset)); 888 __ mov(ebx, FieldOperand(ecx, HeapObject::kMapOffset));
887 __ mov(edx, FieldOperand(ebx, Map::kInstanceDescriptorsOffset)); 889 __ mov(edx, FieldOperand(ebx, Map::kInstanceDescriptorsOffset));
888 __ cmp(edx, Factory::empty_descriptor_array()); 890 __ cmp(edx, isolate()->factory()->empty_descriptor_array());
889 __ j(equal, &call_runtime); 891 __ j(equal, &call_runtime);
890 892
891 // Check that there is an enum cache in the non-empty instance 893 // Check that there is an enum cache in the non-empty instance
892 // descriptors (edx). This is the case if the next enumeration 894 // descriptors (edx). This is the case if the next enumeration
893 // index field does not contain a smi. 895 // index field does not contain a smi.
894 __ mov(edx, FieldOperand(edx, DescriptorArray::kEnumerationIndexOffset)); 896 __ mov(edx, FieldOperand(edx, DescriptorArray::kEnumerationIndexOffset));
895 __ test(edx, Immediate(kSmiTagMask)); 897 __ test(edx, Immediate(kSmiTagMask));
896 __ j(zero, &call_runtime); 898 __ j(zero, &call_runtime);
897 899
898 // For all objects but the receiver, check that the cache is empty. 900 // For all objects but the receiver, check that the cache is empty.
899 NearLabel check_prototype; 901 NearLabel check_prototype;
900 __ cmp(ecx, Operand(eax)); 902 __ cmp(ecx, Operand(eax));
901 __ j(equal, &check_prototype); 903 __ j(equal, &check_prototype);
902 __ mov(edx, FieldOperand(edx, DescriptorArray::kEnumCacheBridgeCacheOffset)); 904 __ mov(edx, FieldOperand(edx, DescriptorArray::kEnumCacheBridgeCacheOffset));
903 __ cmp(edx, Factory::empty_fixed_array()); 905 __ cmp(edx, isolate()->factory()->empty_fixed_array());
904 __ j(not_equal, &call_runtime); 906 __ j(not_equal, &call_runtime);
905 907
906 // Load the prototype from the map and loop if non-null. 908 // Load the prototype from the map and loop if non-null.
907 __ bind(&check_prototype); 909 __ bind(&check_prototype);
908 __ mov(ecx, FieldOperand(ebx, Map::kPrototypeOffset)); 910 __ mov(ecx, FieldOperand(ebx, Map::kPrototypeOffset));
909 __ cmp(ecx, Factory::null_value()); 911 __ cmp(ecx, isolate()->factory()->null_value());
910 __ j(not_equal, &next); 912 __ j(not_equal, &next);
911 913
912 // The enum cache is valid. Load the map of the object being 914 // The enum cache is valid. Load the map of the object being
913 // iterated over and use the cache for the iteration. 915 // iterated over and use the cache for the iteration.
914 NearLabel use_cache; 916 NearLabel use_cache;
915 __ mov(eax, FieldOperand(eax, HeapObject::kMapOffset)); 917 __ mov(eax, FieldOperand(eax, HeapObject::kMapOffset));
916 __ jmp(&use_cache); 918 __ jmp(&use_cache);
917 919
918 // Get the set of properties to enumerate. 920 // Get the set of properties to enumerate.
919 __ bind(&call_runtime); 921 __ bind(&call_runtime);
920 __ push(eax); // Duplicate the enumerable object on the stack. 922 __ push(eax); // Duplicate the enumerable object on the stack.
921 __ CallRuntime(Runtime::kGetPropertyNamesFast, 1); 923 __ CallRuntime(Runtime::kGetPropertyNamesFast, 1);
922 924
923 // If we got a map from the runtime call, we can do a fast 925 // If we got a map from the runtime call, we can do a fast
924 // modification check. Otherwise, we got a fixed array, and we have 926 // modification check. Otherwise, we got a fixed array, and we have
925 // to do a slow check. 927 // to do a slow check.
926 NearLabel fixed_array; 928 NearLabel fixed_array;
927 __ cmp(FieldOperand(eax, HeapObject::kMapOffset), Factory::meta_map()); 929 __ cmp(FieldOperand(eax, HeapObject::kMapOffset),
930 isolate()->factory()->meta_map());
928 __ j(not_equal, &fixed_array); 931 __ j(not_equal, &fixed_array);
929 932
930 // We got a map in register eax. Get the enumeration cache from it. 933 // We got a map in register eax. Get the enumeration cache from it.
931 __ bind(&use_cache); 934 __ bind(&use_cache);
932 __ mov(ecx, FieldOperand(eax, Map::kInstanceDescriptorsOffset)); 935 __ mov(ecx, FieldOperand(eax, Map::kInstanceDescriptorsOffset));
933 __ mov(ecx, FieldOperand(ecx, DescriptorArray::kEnumerationIndexOffset)); 936 __ mov(ecx, FieldOperand(ecx, DescriptorArray::kEnumerationIndexOffset));
934 __ mov(edx, FieldOperand(ecx, DescriptorArray::kEnumCacheBridgeCacheOffset)); 937 __ mov(edx, FieldOperand(ecx, DescriptorArray::kEnumCacheBridgeCacheOffset));
935 938
936 // Setup the four remaining stack slots. 939 // Setup the four remaining stack slots.
937 __ push(eax); // Map. 940 __ push(eax); // Map.
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
1023 !pretenure && 1026 !pretenure &&
1024 scope()->is_function_scope() && 1027 scope()->is_function_scope() &&
1025 info->num_literals() == 0) { 1028 info->num_literals() == 0) {
1026 FastNewClosureStub stub(info->strict_mode() ? kStrictMode : kNonStrictMode); 1029 FastNewClosureStub stub(info->strict_mode() ? kStrictMode : kNonStrictMode);
1027 __ push(Immediate(info)); 1030 __ push(Immediate(info));
1028 __ CallStub(&stub); 1031 __ CallStub(&stub);
1029 } else { 1032 } else {
1030 __ push(esi); 1033 __ push(esi);
1031 __ push(Immediate(info)); 1034 __ push(Immediate(info));
1032 __ push(Immediate(pretenure 1035 __ push(Immediate(pretenure
1033 ? Factory::true_value() 1036 ? isolate()->factory()->true_value()
1034 : Factory::false_value())); 1037 : isolate()->factory()->false_value()));
1035 __ CallRuntime(Runtime::kNewClosure, 3); 1038 __ CallRuntime(Runtime::kNewClosure, 3);
1036 } 1039 }
1037 context()->Plug(eax); 1040 context()->Plug(eax);
1038 } 1041 }
1039 1042
1040 1043
1041 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) { 1044 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
1042 Comment cmnt(masm_, "[ VariableProxy"); 1045 Comment cmnt(masm_, "[ VariableProxy");
1043 EmitVariableLoad(expr->var()); 1046 EmitVariableLoad(expr->var());
1044 } 1047 }
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1076 if (s != NULL && s->is_eval_scope()) { 1079 if (s != NULL && s->is_eval_scope()) {
1077 // Loop up the context chain. There is no frame effect so it is 1080 // Loop up the context chain. There is no frame effect so it is
1078 // safe to use raw labels here. 1081 // safe to use raw labels here.
1079 NearLabel next, fast; 1082 NearLabel next, fast;
1080 if (!context.is(temp)) { 1083 if (!context.is(temp)) {
1081 __ mov(temp, context); 1084 __ mov(temp, context);
1082 } 1085 }
1083 __ bind(&next); 1086 __ bind(&next);
1084 // Terminate at global context. 1087 // Terminate at global context.
1085 __ cmp(FieldOperand(temp, HeapObject::kMapOffset), 1088 __ cmp(FieldOperand(temp, HeapObject::kMapOffset),
1086 Immediate(Factory::global_context_map())); 1089 Immediate(isolate()->factory()->global_context_map()));
1087 __ j(equal, &fast); 1090 __ j(equal, &fast);
1088 // Check that extension is NULL. 1091 // Check that extension is NULL.
1089 __ cmp(ContextOperand(temp, Context::EXTENSION_INDEX), Immediate(0)); 1092 __ cmp(ContextOperand(temp, Context::EXTENSION_INDEX), Immediate(0));
1090 __ j(not_equal, slow); 1093 __ j(not_equal, slow);
1091 // Load next context in chain. 1094 // Load next context in chain.
1092 __ mov(temp, ContextOperand(temp, Context::CLOSURE_INDEX)); 1095 __ mov(temp, ContextOperand(temp, Context::CLOSURE_INDEX));
1093 __ mov(temp, FieldOperand(temp, JSFunction::kContextOffset)); 1096 __ mov(temp, FieldOperand(temp, JSFunction::kContextOffset));
1094 __ jmp(&next); 1097 __ jmp(&next);
1095 __ bind(&fast); 1098 __ bind(&fast);
1096 } 1099 }
1097 1100
1098 // All extension objects were empty and it is safe to use a global 1101 // All extension objects were empty and it is safe to use a global
1099 // load IC call. 1102 // load IC call.
1100 __ mov(eax, GlobalObjectOperand()); 1103 __ mov(eax, GlobalObjectOperand());
1101 __ mov(ecx, slot->var()->name()); 1104 __ mov(ecx, slot->var()->name());
1102 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); 1105 Handle<Code> ic(isolate()->builtins()->builtin(
1106 Builtins::LoadIC_Initialize));
1103 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF) 1107 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF)
1104 ? RelocInfo::CODE_TARGET 1108 ? RelocInfo::CODE_TARGET
1105 : RelocInfo::CODE_TARGET_CONTEXT; 1109 : RelocInfo::CODE_TARGET_CONTEXT;
1106 EmitCallIC(ic, mode); 1110 EmitCallIC(ic, mode);
1107 } 1111 }
1108 1112
1109 1113
1110 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions( 1114 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(
1111 Slot* slot, 1115 Slot* slot,
1112 Label* slow) { 1116 Label* slow) {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1153 EmitLoadGlobalSlotCheckExtensions(slot, typeof_state, slow); 1157 EmitLoadGlobalSlotCheckExtensions(slot, typeof_state, slow);
1154 __ jmp(done); 1158 __ jmp(done);
1155 } else if (slot->var()->mode() == Variable::DYNAMIC_LOCAL) { 1159 } else if (slot->var()->mode() == Variable::DYNAMIC_LOCAL) {
1156 Slot* potential_slot = slot->var()->local_if_not_shadowed()->AsSlot(); 1160 Slot* potential_slot = slot->var()->local_if_not_shadowed()->AsSlot();
1157 Expression* rewrite = slot->var()->local_if_not_shadowed()->rewrite(); 1161 Expression* rewrite = slot->var()->local_if_not_shadowed()->rewrite();
1158 if (potential_slot != NULL) { 1162 if (potential_slot != NULL) {
1159 // Generate fast case for locals that rewrite to slots. 1163 // Generate fast case for locals that rewrite to slots.
1160 __ mov(eax, 1164 __ mov(eax,
1161 ContextSlotOperandCheckExtensions(potential_slot, slow)); 1165 ContextSlotOperandCheckExtensions(potential_slot, slow));
1162 if (potential_slot->var()->mode() == Variable::CONST) { 1166 if (potential_slot->var()->mode() == Variable::CONST) {
1163 __ cmp(eax, Factory::the_hole_value()); 1167 __ cmp(eax, isolate()->factory()->the_hole_value());
1164 __ j(not_equal, done); 1168 __ j(not_equal, done);
1165 __ mov(eax, Factory::undefined_value()); 1169 __ mov(eax, isolate()->factory()->undefined_value());
1166 } 1170 }
1167 __ jmp(done); 1171 __ jmp(done);
1168 } else if (rewrite != NULL) { 1172 } else if (rewrite != NULL) {
1169 // Generate fast case for calls of an argument function. 1173 // Generate fast case for calls of an argument function.
1170 Property* property = rewrite->AsProperty(); 1174 Property* property = rewrite->AsProperty();
1171 if (property != NULL) { 1175 if (property != NULL) {
1172 VariableProxy* obj_proxy = property->obj()->AsVariableProxy(); 1176 VariableProxy* obj_proxy = property->obj()->AsVariableProxy();
1173 Literal* key_literal = property->key()->AsLiteral(); 1177 Literal* key_literal = property->key()->AsLiteral();
1174 if (obj_proxy != NULL && 1178 if (obj_proxy != NULL &&
1175 key_literal != NULL && 1179 key_literal != NULL &&
1176 obj_proxy->IsArguments() && 1180 obj_proxy->IsArguments() &&
1177 key_literal->handle()->IsSmi()) { 1181 key_literal->handle()->IsSmi()) {
1178 // Load arguments object if there are no eval-introduced 1182 // Load arguments object if there are no eval-introduced
1179 // variables. Then load the argument from the arguments 1183 // variables. Then load the argument from the arguments
1180 // object using keyed load. 1184 // object using keyed load.
1181 __ mov(edx, 1185 __ mov(edx,
1182 ContextSlotOperandCheckExtensions(obj_proxy->var()->AsSlot(), 1186 ContextSlotOperandCheckExtensions(obj_proxy->var()->AsSlot(),
1183 slow)); 1187 slow));
1184 __ mov(eax, Immediate(key_literal->handle())); 1188 __ mov(eax, Immediate(key_literal->handle()));
1185 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); 1189 Handle<Code> ic(isolate()->builtins()->builtin(
1190 Builtins::KeyedLoadIC_Initialize));
1186 EmitCallIC(ic, RelocInfo::CODE_TARGET); 1191 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1187 __ jmp(done); 1192 __ jmp(done);
1188 } 1193 }
1189 } 1194 }
1190 } 1195 }
1191 } 1196 }
1192 } 1197 }
1193 1198
1194 1199
1195 void FullCodeGenerator::EmitVariableLoad(Variable* var) { 1200 void FullCodeGenerator::EmitVariableLoad(Variable* var) {
1196 // Four cases: non-this global variables, lookup slots, all other 1201 // Four cases: non-this global variables, lookup slots, all other
1197 // types of slots, and parameters that rewrite to explicit property 1202 // types of slots, and parameters that rewrite to explicit property
1198 // accesses on the arguments object. 1203 // accesses on the arguments object.
1199 Slot* slot = var->AsSlot(); 1204 Slot* slot = var->AsSlot();
1200 Property* property = var->AsProperty(); 1205 Property* property = var->AsProperty();
1201 1206
1202 if (var->is_global() && !var->is_this()) { 1207 if (var->is_global() && !var->is_this()) {
1203 Comment cmnt(masm_, "Global variable"); 1208 Comment cmnt(masm_, "Global variable");
1204 // Use inline caching. Variable name is passed in ecx and the global 1209 // Use inline caching. Variable name is passed in ecx and the global
1205 // object on the stack. 1210 // object on the stack.
1206 __ mov(eax, GlobalObjectOperand()); 1211 __ mov(eax, GlobalObjectOperand());
1207 __ mov(ecx, var->name()); 1212 __ mov(ecx, var->name());
1208 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); 1213 Handle<Code> ic(isolate()->builtins()->builtin(
1214 Builtins::LoadIC_Initialize));
1209 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); 1215 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT);
1210 context()->Plug(eax); 1216 context()->Plug(eax);
1211 1217
1212 } else if (slot != NULL && slot->type() == Slot::LOOKUP) { 1218 } else if (slot != NULL && slot->type() == Slot::LOOKUP) {
1213 Label done, slow; 1219 Label done, slow;
1214 1220
1215 // Generate code for loading from variables potentially shadowed 1221 // Generate code for loading from variables potentially shadowed
1216 // by eval-introduced variables. 1222 // by eval-introduced variables.
1217 EmitDynamicLoadFromSlotFastCase(slot, NOT_INSIDE_TYPEOF, &slow, &done); 1223 EmitDynamicLoadFromSlotFastCase(slot, NOT_INSIDE_TYPEOF, &slow, &done);
1218 1224
1219 __ bind(&slow); 1225 __ bind(&slow);
1220 Comment cmnt(masm_, "Lookup slot"); 1226 Comment cmnt(masm_, "Lookup slot");
1221 __ push(esi); // Context. 1227 __ push(esi); // Context.
1222 __ push(Immediate(var->name())); 1228 __ push(Immediate(var->name()));
1223 __ CallRuntime(Runtime::kLoadContextSlot, 2); 1229 __ CallRuntime(Runtime::kLoadContextSlot, 2);
1224 __ bind(&done); 1230 __ bind(&done);
1225 1231
1226 context()->Plug(eax); 1232 context()->Plug(eax);
1227 1233
1228 } else if (slot != NULL) { 1234 } else if (slot != NULL) {
1229 Comment cmnt(masm_, (slot->type() == Slot::CONTEXT) 1235 Comment cmnt(masm_, (slot->type() == Slot::CONTEXT)
1230 ? "Context slot" 1236 ? "Context slot"
1231 : "Stack slot"); 1237 : "Stack slot");
1232 if (var->mode() == Variable::CONST) { 1238 if (var->mode() == Variable::CONST) {
1233 // Constants may be the hole value if they have not been initialized. 1239 // Constants may be the hole value if they have not been initialized.
1234 // Unhole them. 1240 // Unhole them.
1235 NearLabel done; 1241 NearLabel done;
1236 MemOperand slot_operand = EmitSlotSearch(slot, eax); 1242 MemOperand slot_operand = EmitSlotSearch(slot, eax);
1237 __ mov(eax, slot_operand); 1243 __ mov(eax, slot_operand);
1238 __ cmp(eax, Factory::the_hole_value()); 1244 __ cmp(eax, isolate()->factory()->the_hole_value());
1239 __ j(not_equal, &done); 1245 __ j(not_equal, &done);
1240 __ mov(eax, Factory::undefined_value()); 1246 __ mov(eax, isolate()->factory()->undefined_value());
1241 __ bind(&done); 1247 __ bind(&done);
1242 context()->Plug(eax); 1248 context()->Plug(eax);
1243 } else { 1249 } else {
1244 context()->Plug(slot); 1250 context()->Plug(slot);
1245 } 1251 }
1246 1252
1247 } else { 1253 } else {
1248 Comment cmnt(masm_, "Rewritten parameter"); 1254 Comment cmnt(masm_, "Rewritten parameter");
1249 ASSERT_NOT_NULL(property); 1255 ASSERT_NOT_NULL(property);
1250 // Rewritten parameter accesses are of the form "slot[literal]". 1256 // Rewritten parameter accesses are of the form "slot[literal]".
(...skipping 10 matching lines...) Expand all
1261 1267
1262 // Assert that the key is a smi. 1268 // Assert that the key is a smi.
1263 Literal* key_literal = property->key()->AsLiteral(); 1269 Literal* key_literal = property->key()->AsLiteral();
1264 ASSERT_NOT_NULL(key_literal); 1270 ASSERT_NOT_NULL(key_literal);
1265 ASSERT(key_literal->handle()->IsSmi()); 1271 ASSERT(key_literal->handle()->IsSmi());
1266 1272
1267 // Load the key. 1273 // Load the key.
1268 __ mov(eax, Immediate(key_literal->handle())); 1274 __ mov(eax, Immediate(key_literal->handle()));
1269 1275
1270 // Do a keyed property load. 1276 // Do a keyed property load.
1271 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); 1277 Handle<Code> ic(isolate()->builtins()->builtin(
1278 Builtins::KeyedLoadIC_Initialize));
1272 EmitCallIC(ic, RelocInfo::CODE_TARGET); 1279 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1273 1280
1274 // Drop key and object left on the stack by IC. 1281 // Drop key and object left on the stack by IC.
1275 context()->Plug(eax); 1282 context()->Plug(eax);
1276 } 1283 }
1277 } 1284 }
1278 1285
1279 1286
1280 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { 1287 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
1281 Comment cmnt(masm_, "[ RegExpLiteral"); 1288 Comment cmnt(masm_, "[ RegExpLiteral");
1282 NearLabel materialized; 1289 NearLabel materialized;
1283 // Registers will be used as follows: 1290 // Registers will be used as follows:
1284 // edi = JS function. 1291 // edi = JS function.
1285 // ecx = literals array. 1292 // ecx = literals array.
1286 // ebx = regexp literal. 1293 // ebx = regexp literal.
1287 // eax = regexp literal clone. 1294 // eax = regexp literal clone.
1288 __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); 1295 __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
1289 __ mov(ecx, FieldOperand(edi, JSFunction::kLiteralsOffset)); 1296 __ mov(ecx, FieldOperand(edi, JSFunction::kLiteralsOffset));
1290 int literal_offset = 1297 int literal_offset =
1291 FixedArray::kHeaderSize + expr->literal_index() * kPointerSize; 1298 FixedArray::kHeaderSize + expr->literal_index() * kPointerSize;
1292 __ mov(ebx, FieldOperand(ecx, literal_offset)); 1299 __ mov(ebx, FieldOperand(ecx, literal_offset));
1293 __ cmp(ebx, Factory::undefined_value()); 1300 __ cmp(ebx, isolate()->factory()->undefined_value());
1294 __ j(not_equal, &materialized); 1301 __ j(not_equal, &materialized);
1295 1302
1296 // Create regexp literal using runtime function 1303 // Create regexp literal using runtime function
1297 // Result will be in eax. 1304 // Result will be in eax.
1298 __ push(ecx); 1305 __ push(ecx);
1299 __ push(Immediate(Smi::FromInt(expr->literal_index()))); 1306 __ push(Immediate(Smi::FromInt(expr->literal_index())));
1300 __ push(Immediate(expr->pattern())); 1307 __ push(Immediate(expr->pattern()));
1301 __ push(Immediate(expr->flags())); 1308 __ push(Immediate(expr->flags()));
1302 __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4); 1309 __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4);
1303 __ mov(ebx, eax); 1310 __ mov(ebx, eax);
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
1366 switch (property->kind()) { 1373 switch (property->kind()) {
1367 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1374 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1368 ASSERT(!CompileTimeValue::IsCompileTimeValue(value)); 1375 ASSERT(!CompileTimeValue::IsCompileTimeValue(value));
1369 // Fall through. 1376 // Fall through.
1370 case ObjectLiteral::Property::COMPUTED: 1377 case ObjectLiteral::Property::COMPUTED:
1371 if (key->handle()->IsSymbol()) { 1378 if (key->handle()->IsSymbol()) {
1372 if (property->emit_store()) { 1379 if (property->emit_store()) {
1373 VisitForAccumulatorValue(value); 1380 VisitForAccumulatorValue(value);
1374 __ mov(ecx, Immediate(key->handle())); 1381 __ mov(ecx, Immediate(key->handle()));
1375 __ mov(edx, Operand(esp, 0)); 1382 __ mov(edx, Operand(esp, 0));
1376 Handle<Code> ic(Builtins::builtin( 1383 Handle<Code> ic(isolate()->builtins()->builtin(
1377 is_strict_mode() ? Builtins::StoreIC_Initialize_Strict 1384 is_strict_mode() ? Builtins::StoreIC_Initialize_Strict
1378 : Builtins::StoreIC_Initialize)); 1385 : Builtins::StoreIC_Initialize));
1379 EmitCallIC(ic, RelocInfo::CODE_TARGET); 1386 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1380 PrepareForBailoutForId(key->id(), NO_REGISTERS); 1387 PrepareForBailoutForId(key->id(), NO_REGISTERS);
1381 } else { 1388 } else {
1382 VisitForEffect(value); 1389 VisitForEffect(value);
1383 } 1390 }
1384 break; 1391 break;
1385 } 1392 }
1386 // Fall through. 1393 // Fall through.
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1420 void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { 1427 void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
1421 Comment cmnt(masm_, "[ ArrayLiteral"); 1428 Comment cmnt(masm_, "[ ArrayLiteral");
1422 1429
1423 ZoneList<Expression*>* subexprs = expr->values(); 1430 ZoneList<Expression*>* subexprs = expr->values();
1424 int length = subexprs->length(); 1431 int length = subexprs->length();
1425 1432
1426 __ mov(ebx, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); 1433 __ mov(ebx, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
1427 __ push(FieldOperand(ebx, JSFunction::kLiteralsOffset)); 1434 __ push(FieldOperand(ebx, JSFunction::kLiteralsOffset));
1428 __ push(Immediate(Smi::FromInt(expr->literal_index()))); 1435 __ push(Immediate(Smi::FromInt(expr->literal_index())));
1429 __ push(Immediate(expr->constant_elements())); 1436 __ push(Immediate(expr->constant_elements()));
1430 if (expr->constant_elements()->map() == Heap::fixed_cow_array_map()) { 1437 if (expr->constant_elements()->map() ==
1438 isolate()->heap()->fixed_cow_array_map()) {
1431 ASSERT(expr->depth() == 1); 1439 ASSERT(expr->depth() == 1);
1432 FastCloneShallowArrayStub stub( 1440 FastCloneShallowArrayStub stub(
1433 FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS, length); 1441 FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS, length);
1434 __ CallStub(&stub); 1442 __ CallStub(&stub);
1435 __ IncrementCounter(&Counters::cow_arrays_created_stub, 1); 1443 __ IncrementCounter(isolate()->counters()->cow_arrays_created_stub(), 1);
1436 } else if (expr->depth() > 1) { 1444 } else if (expr->depth() > 1) {
1437 __ CallRuntime(Runtime::kCreateArrayLiteral, 3); 1445 __ CallRuntime(Runtime::kCreateArrayLiteral, 3);
1438 } else if (length > FastCloneShallowArrayStub::kMaximumClonedLength) { 1446 } else if (length > FastCloneShallowArrayStub::kMaximumClonedLength) {
1439 __ CallRuntime(Runtime::kCreateArrayLiteralShallow, 3); 1447 __ CallRuntime(Runtime::kCreateArrayLiteralShallow, 3);
1440 } else { 1448 } else {
1441 FastCloneShallowArrayStub stub( 1449 FastCloneShallowArrayStub stub(
1442 FastCloneShallowArrayStub::CLONE_ELEMENTS, length); 1450 FastCloneShallowArrayStub::CLONE_ELEMENTS, length);
1443 __ CallStub(&stub); 1451 __ CallStub(&stub);
1444 } 1452 }
1445 1453
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
1610 EmitKeyedPropertyAssignment(expr); 1618 EmitKeyedPropertyAssignment(expr);
1611 break; 1619 break;
1612 } 1620 }
1613 } 1621 }
1614 1622
1615 1623
1616 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { 1624 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
1617 SetSourcePosition(prop->position()); 1625 SetSourcePosition(prop->position());
1618 Literal* key = prop->key()->AsLiteral(); 1626 Literal* key = prop->key()->AsLiteral();
1619 __ mov(ecx, Immediate(key->handle())); 1627 __ mov(ecx, Immediate(key->handle()));
1620 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); 1628 Handle<Code> ic(isolate()->builtins()->builtin(
1629 Builtins::LoadIC_Initialize));
1621 EmitCallIC(ic, RelocInfo::CODE_TARGET); 1630 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1622 } 1631 }
1623 1632
1624 1633
1625 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { 1634 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
1626 SetSourcePosition(prop->position()); 1635 SetSourcePosition(prop->position());
1627 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); 1636 Handle<Code> ic(isolate()->builtins()->builtin(
1637 Builtins::KeyedLoadIC_Initialize));
1628 EmitCallIC(ic, RelocInfo::CODE_TARGET); 1638 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1629 } 1639 }
1630 1640
1631 1641
1632 void FullCodeGenerator::EmitInlineSmiBinaryOp(Expression* expr, 1642 void FullCodeGenerator::EmitInlineSmiBinaryOp(Expression* expr,
1633 Token::Value op, 1643 Token::Value op,
1634 OverwriteMode mode, 1644 OverwriteMode mode,
1635 Expression* left, 1645 Expression* left,
1636 Expression* right) { 1646 Expression* right) {
1637 // Do combined smi check of the operands. Left operand is on the 1647 // Do combined smi check of the operands. Left operand is on the
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
1758 EffectContext context(this); 1768 EffectContext context(this);
1759 EmitVariableAssignment(var, Token::ASSIGN); 1769 EmitVariableAssignment(var, Token::ASSIGN);
1760 break; 1770 break;
1761 } 1771 }
1762 case NAMED_PROPERTY: { 1772 case NAMED_PROPERTY: {
1763 __ push(eax); // Preserve value. 1773 __ push(eax); // Preserve value.
1764 VisitForAccumulatorValue(prop->obj()); 1774 VisitForAccumulatorValue(prop->obj());
1765 __ mov(edx, eax); 1775 __ mov(edx, eax);
1766 __ pop(eax); // Restore value. 1776 __ pop(eax); // Restore value.
1767 __ mov(ecx, prop->key()->AsLiteral()->handle()); 1777 __ mov(ecx, prop->key()->AsLiteral()->handle());
1768 Handle<Code> ic(Builtins::builtin( 1778 Handle<Code> ic(isolate()->builtins()->builtin(
1769 is_strict_mode() ? Builtins::StoreIC_Initialize_Strict 1779 is_strict_mode() ? Builtins::StoreIC_Initialize_Strict
1770 : Builtins::StoreIC_Initialize)); 1780 : Builtins::StoreIC_Initialize));
1771 EmitCallIC(ic, RelocInfo::CODE_TARGET); 1781 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1772 break; 1782 break;
1773 } 1783 }
1774 case KEYED_PROPERTY: { 1784 case KEYED_PROPERTY: {
1775 __ push(eax); // Preserve value. 1785 __ push(eax); // Preserve value.
1776 if (prop->is_synthetic()) { 1786 if (prop->is_synthetic()) {
1777 ASSERT(prop->obj()->AsVariableProxy() != NULL); 1787 ASSERT(prop->obj()->AsVariableProxy() != NULL);
1778 ASSERT(prop->key()->AsLiteral() != NULL); 1788 ASSERT(prop->key()->AsLiteral() != NULL);
1779 { AccumulatorValueContext for_object(this); 1789 { AccumulatorValueContext for_object(this);
1780 EmitVariableLoad(prop->obj()->AsVariableProxy()->var()); 1790 EmitVariableLoad(prop->obj()->AsVariableProxy()->var());
1781 } 1791 }
1782 __ mov(edx, eax); 1792 __ mov(edx, eax);
1783 __ Set(ecx, Immediate(prop->key()->AsLiteral()->handle())); 1793 __ Set(ecx, Immediate(prop->key()->AsLiteral()->handle()));
1784 } else { 1794 } else {
1785 VisitForStackValue(prop->obj()); 1795 VisitForStackValue(prop->obj());
1786 VisitForAccumulatorValue(prop->key()); 1796 VisitForAccumulatorValue(prop->key());
1787 __ mov(ecx, eax); 1797 __ mov(ecx, eax);
1788 __ pop(edx); 1798 __ pop(edx);
1789 } 1799 }
1790 __ pop(eax); // Restore value. 1800 __ pop(eax); // Restore value.
1791 Handle<Code> ic(Builtins::builtin( 1801 Handle<Code> ic(isolate()->builtins()->builtin(
1792 is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict 1802 is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict
1793 : Builtins::KeyedStoreIC_Initialize)); 1803 : Builtins::KeyedStoreIC_Initialize));
1794 EmitCallIC(ic, RelocInfo::CODE_TARGET); 1804 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1795 break; 1805 break;
1796 } 1806 }
1797 } 1807 }
1798 PrepareForBailoutForId(bailout_ast_id, TOS_REG); 1808 PrepareForBailoutForId(bailout_ast_id, TOS_REG);
1799 context()->Plug(eax); 1809 context()->Plug(eax);
1800 } 1810 }
1801 1811
1802 1812
1803 void FullCodeGenerator::EmitVariableAssignment(Variable* var, 1813 void FullCodeGenerator::EmitVariableAssignment(Variable* var,
1804 Token::Value op) { 1814 Token::Value op) {
1805 // Left-hand sides that rewrite to explicit property accesses do not reach 1815 // Left-hand sides that rewrite to explicit property accesses do not reach
1806 // here. 1816 // here.
1807 ASSERT(var != NULL); 1817 ASSERT(var != NULL);
1808 ASSERT(var->is_global() || var->AsSlot() != NULL); 1818 ASSERT(var->is_global() || var->AsSlot() != NULL);
1809 1819
1810 if (var->is_global()) { 1820 if (var->is_global()) {
1811 ASSERT(!var->is_this()); 1821 ASSERT(!var->is_this());
1812 // Assignment to a global variable. Use inline caching for the 1822 // Assignment to a global variable. Use inline caching for the
1813 // assignment. Right-hand-side value is passed in eax, variable name in 1823 // assignment. Right-hand-side value is passed in eax, variable name in
1814 // ecx, and the global object on the stack. 1824 // ecx, and the global object on the stack.
1815 __ mov(ecx, var->name()); 1825 __ mov(ecx, var->name());
1816 __ mov(edx, GlobalObjectOperand()); 1826 __ mov(edx, GlobalObjectOperand());
1817 Handle<Code> ic(Builtins::builtin( 1827 Handle<Code> ic(isolate()->builtins()->builtin(
1818 is_strict_mode() ? Builtins::StoreIC_Initialize_Strict 1828 is_strict_mode() ? Builtins::StoreIC_Initialize_Strict
1819 : Builtins::StoreIC_Initialize)); 1829 : Builtins::StoreIC_Initialize));
1820 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); 1830 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT);
1821 1831
1822 } else if (op == Token::INIT_CONST) { 1832 } else if (op == Token::INIT_CONST) {
1823 // Like var declarations, const declarations are hoisted to function 1833 // Like var declarations, const declarations are hoisted to function
1824 // scope. However, unlike var initializers, const initializers are able 1834 // scope. However, unlike var initializers, const initializers are able
1825 // to drill a hole to that function context, even from inside a 'with' 1835 // to drill a hole to that function context, even from inside a 'with'
1826 // context. We thus bypass the normal static scope lookup. 1836 // context. We thus bypass the normal static scope lookup.
1827 Slot* slot = var->AsSlot(); 1837 Slot* slot = var->AsSlot();
1828 Label skip; 1838 Label skip;
1829 switch (slot->type()) { 1839 switch (slot->type()) {
1830 case Slot::PARAMETER: 1840 case Slot::PARAMETER:
1831 // No const parameters. 1841 // No const parameters.
1832 UNREACHABLE(); 1842 UNREACHABLE();
1833 break; 1843 break;
1834 case Slot::LOCAL: 1844 case Slot::LOCAL:
1835 __ mov(edx, Operand(ebp, SlotOffset(slot))); 1845 __ mov(edx, Operand(ebp, SlotOffset(slot)));
1836 __ cmp(edx, Factory::the_hole_value()); 1846 __ cmp(edx, isolate()->factory()->the_hole_value());
1837 __ j(not_equal, &skip); 1847 __ j(not_equal, &skip);
1838 __ mov(Operand(ebp, SlotOffset(slot)), eax); 1848 __ mov(Operand(ebp, SlotOffset(slot)), eax);
1839 break; 1849 break;
1840 case Slot::CONTEXT: { 1850 case Slot::CONTEXT: {
1841 __ mov(ecx, ContextOperand(esi, Context::FCONTEXT_INDEX)); 1851 __ mov(ecx, ContextOperand(esi, Context::FCONTEXT_INDEX));
1842 __ mov(edx, ContextOperand(ecx, slot->index())); 1852 __ mov(edx, ContextOperand(ecx, slot->index()));
1843 __ cmp(edx, Factory::the_hole_value()); 1853 __ cmp(edx, isolate()->factory()->the_hole_value());
1844 __ j(not_equal, &skip); 1854 __ j(not_equal, &skip);
1845 __ mov(ContextOperand(ecx, slot->index()), eax); 1855 __ mov(ContextOperand(ecx, slot->index()), eax);
1846 int offset = Context::SlotOffset(slot->index()); 1856 int offset = Context::SlotOffset(slot->index());
1847 __ mov(edx, eax); // Preserve the stored value in eax. 1857 __ mov(edx, eax); // Preserve the stored value in eax.
1848 __ RecordWrite(ecx, offset, edx, ebx, kDontSaveFPRegs); 1858 __ RecordWrite(ecx, offset, edx, ebx, kDontSaveFPRegs);
1849 break; 1859 break;
1850 } 1860 }
1851 case Slot::LOOKUP: 1861 case Slot::LOOKUP:
1852 __ push(eax); 1862 __ push(eax);
1853 __ push(esi); 1863 __ push(esi);
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1911 } 1921 }
1912 1922
1913 // Record source code position before IC call. 1923 // Record source code position before IC call.
1914 SetSourcePosition(expr->position()); 1924 SetSourcePosition(expr->position());
1915 __ mov(ecx, prop->key()->AsLiteral()->handle()); 1925 __ mov(ecx, prop->key()->AsLiteral()->handle());
1916 if (expr->ends_initialization_block()) { 1926 if (expr->ends_initialization_block()) {
1917 __ mov(edx, Operand(esp, 0)); 1927 __ mov(edx, Operand(esp, 0));
1918 } else { 1928 } else {
1919 __ pop(edx); 1929 __ pop(edx);
1920 } 1930 }
1921 Handle<Code> ic(Builtins::builtin( 1931 Handle<Code> ic(isolate()->builtins()->builtin(
1922 is_strict_mode() ? Builtins::StoreIC_Initialize_Strict 1932 is_strict_mode() ? Builtins::StoreIC_Initialize_Strict
1923 : Builtins::StoreIC_Initialize)); 1933 : Builtins::StoreIC_Initialize));
1924 EmitCallIC(ic, RelocInfo::CODE_TARGET); 1934 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1925 1935
1926 // If the assignment ends an initialization block, revert to fast case. 1936 // If the assignment ends an initialization block, revert to fast case.
1927 if (expr->ends_initialization_block()) { 1937 if (expr->ends_initialization_block()) {
1928 __ push(eax); // Result of assignment, saved even if not needed. 1938 __ push(eax); // Result of assignment, saved even if not needed.
1929 __ push(Operand(esp, kPointerSize)); // Receiver is under value. 1939 __ push(Operand(esp, kPointerSize)); // Receiver is under value.
1930 __ CallRuntime(Runtime::kToFastProperties, 1); 1940 __ CallRuntime(Runtime::kToFastProperties, 1);
1931 __ pop(eax); 1941 __ pop(eax);
(...skipping 19 matching lines...) Expand all
1951 } 1961 }
1952 1962
1953 __ pop(ecx); 1963 __ pop(ecx);
1954 if (expr->ends_initialization_block()) { 1964 if (expr->ends_initialization_block()) {
1955 __ mov(edx, Operand(esp, 0)); // Leave receiver on the stack for later. 1965 __ mov(edx, Operand(esp, 0)); // Leave receiver on the stack for later.
1956 } else { 1966 } else {
1957 __ pop(edx); 1967 __ pop(edx);
1958 } 1968 }
1959 // Record source code position before IC call. 1969 // Record source code position before IC call.
1960 SetSourcePosition(expr->position()); 1970 SetSourcePosition(expr->position());
1961 Handle<Code> ic(Builtins::builtin( 1971 Handle<Code> ic(isolate()->builtins()->builtin(
1962 is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict 1972 is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict
1963 : Builtins::KeyedStoreIC_Initialize)); 1973 : Builtins::KeyedStoreIC_Initialize));
1964 EmitCallIC(ic, RelocInfo::CODE_TARGET); 1974 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1965 1975
1966 // If the assignment ends an initialization block, revert to fast case. 1976 // If the assignment ends an initialization block, revert to fast case.
1967 if (expr->ends_initialization_block()) { 1977 if (expr->ends_initialization_block()) {
1968 __ pop(edx); 1978 __ pop(edx);
1969 __ push(eax); // Result of assignment, saved even if not needed. 1979 __ push(eax); // Result of assignment, saved even if not needed.
1970 __ push(edx); 1980 __ push(edx);
1971 __ CallRuntime(Runtime::kToFastProperties, 1); 1981 __ CallRuntime(Runtime::kToFastProperties, 1);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
2003 int arg_count = args->length(); 2013 int arg_count = args->length();
2004 { PreservePositionScope scope(masm()->positions_recorder()); 2014 { PreservePositionScope scope(masm()->positions_recorder());
2005 for (int i = 0; i < arg_count; i++) { 2015 for (int i = 0; i < arg_count; i++) {
2006 VisitForStackValue(args->at(i)); 2016 VisitForStackValue(args->at(i));
2007 } 2017 }
2008 __ Set(ecx, Immediate(name)); 2018 __ Set(ecx, Immediate(name));
2009 } 2019 }
2010 // Record source position of the IC call. 2020 // Record source position of the IC call.
2011 SetSourcePosition(expr->position()); 2021 SetSourcePosition(expr->position());
2012 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; 2022 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
2013 Handle<Code> ic = StubCache::ComputeCallInitialize(arg_count, in_loop); 2023 Handle<Code> ic = isolate()->stub_cache()->ComputeCallInitialize(
2024 arg_count, in_loop);
2014 EmitCallIC(ic, mode); 2025 EmitCallIC(ic, mode);
2015 RecordJSReturnSite(expr); 2026 RecordJSReturnSite(expr);
2016 // Restore context register. 2027 // Restore context register.
2017 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2028 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2018 context()->Plug(eax); 2029 context()->Plug(eax);
2019 } 2030 }
2020 2031
2021 2032
2022 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, 2033 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr,
2023 Expression* key, 2034 Expression* key,
(...skipping 11 matching lines...) Expand all
2035 ZoneList<Expression*>* args = expr->arguments(); 2046 ZoneList<Expression*>* args = expr->arguments();
2036 int arg_count = args->length(); 2047 int arg_count = args->length();
2037 { PreservePositionScope scope(masm()->positions_recorder()); 2048 { PreservePositionScope scope(masm()->positions_recorder());
2038 for (int i = 0; i < arg_count; i++) { 2049 for (int i = 0; i < arg_count; i++) {
2039 VisitForStackValue(args->at(i)); 2050 VisitForStackValue(args->at(i));
2040 } 2051 }
2041 } 2052 }
2042 // Record source position of the IC call. 2053 // Record source position of the IC call.
2043 SetSourcePosition(expr->position()); 2054 SetSourcePosition(expr->position());
2044 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; 2055 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
2045 Handle<Code> ic = StubCache::ComputeKeyedCallInitialize(arg_count, in_loop); 2056 Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedCallInitialize(
2057 arg_count, in_loop);
2046 __ mov(ecx, Operand(esp, (arg_count + 1) * kPointerSize)); // Key. 2058 __ mov(ecx, Operand(esp, (arg_count + 1) * kPointerSize)); // Key.
2047 EmitCallIC(ic, mode); 2059 EmitCallIC(ic, mode);
2048 RecordJSReturnSite(expr); 2060 RecordJSReturnSite(expr);
2049 // Restore context register. 2061 // Restore context register.
2050 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2062 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2051 context()->DropAndPlug(1, eax); // Drop the key still on the stack. 2063 context()->DropAndPlug(1, eax); // Drop the key still on the stack.
2052 } 2064 }
2053 2065
2054 2066
2055 void FullCodeGenerator::EmitCallWithStub(Call* expr) { 2067 void FullCodeGenerator::EmitCallWithStub(Call* expr) {
(...skipping 16 matching lines...) Expand all
2072 context()->DropAndPlug(1, eax); 2084 context()->DropAndPlug(1, eax);
2073 } 2085 }
2074 2086
2075 2087
2076 void FullCodeGenerator::EmitResolvePossiblyDirectEval(ResolveEvalFlag flag, 2088 void FullCodeGenerator::EmitResolvePossiblyDirectEval(ResolveEvalFlag flag,
2077 int arg_count) { 2089 int arg_count) {
2078 // Push copy of the first argument or undefined if it doesn't exist. 2090 // Push copy of the first argument or undefined if it doesn't exist.
2079 if (arg_count > 0) { 2091 if (arg_count > 0) {
2080 __ push(Operand(esp, arg_count * kPointerSize)); 2092 __ push(Operand(esp, arg_count * kPointerSize));
2081 } else { 2093 } else {
2082 __ push(Immediate(Factory::undefined_value())); 2094 __ push(Immediate(FACTORY->undefined_value()));
2083 } 2095 }
2084 2096
2085 // Push the receiver of the enclosing function. 2097 // Push the receiver of the enclosing function.
2086 __ push(Operand(ebp, (2 + scope()->num_parameters()) * kPointerSize)); 2098 __ push(Operand(ebp, (2 + scope()->num_parameters()) * kPointerSize));
2087 2099
2088 // Push the strict mode flag. 2100 // Push the strict mode flag.
2089 __ push(Immediate(Smi::FromInt(strict_mode_flag()))); 2101 __ push(Immediate(Smi::FromInt(strict_mode_flag())));
2090 2102
2091 __ CallRuntime(flag == SKIP_CONTEXT_LOOKUP 2103 __ CallRuntime(flag == SKIP_CONTEXT_LOOKUP
2092 ? Runtime::kResolvePossiblyDirectEvalNoLookup 2104 ? Runtime::kResolvePossiblyDirectEvalNoLookup
(...skipping 15 matching lines...) Expand all
2108 if (var != NULL && var->is_possibly_eval()) { 2120 if (var != NULL && var->is_possibly_eval()) {
2109 // In a call to eval, we first call %ResolvePossiblyDirectEval to 2121 // In a call to eval, we first call %ResolvePossiblyDirectEval to
2110 // resolve the function we need to call and the receiver of the 2122 // resolve the function we need to call and the receiver of the
2111 // call. Then we call the resolved function using the given 2123 // call. Then we call the resolved function using the given
2112 // arguments. 2124 // arguments.
2113 ZoneList<Expression*>* args = expr->arguments(); 2125 ZoneList<Expression*>* args = expr->arguments();
2114 int arg_count = args->length(); 2126 int arg_count = args->length();
2115 { PreservePositionScope pos_scope(masm()->positions_recorder()); 2127 { PreservePositionScope pos_scope(masm()->positions_recorder());
2116 VisitForStackValue(fun); 2128 VisitForStackValue(fun);
2117 // Reserved receiver slot. 2129 // Reserved receiver slot.
2118 __ push(Immediate(Factory::undefined_value())); 2130 __ push(Immediate(isolate()->factory()->undefined_value()));
2119 2131
2120 // Push the arguments. 2132 // Push the arguments.
2121 for (int i = 0; i < arg_count; i++) { 2133 for (int i = 0; i < arg_count; i++) {
2122 VisitForStackValue(args->at(i)); 2134 VisitForStackValue(args->at(i));
2123 } 2135 }
2124 2136
2125 // If we know that eval can only be shadowed by eval-introduced 2137 // If we know that eval can only be shadowed by eval-introduced
2126 // variables we attempt to load the global eval function directly 2138 // variables we attempt to load the global eval function directly
2127 // in generated code. If we succeed, there is no need to perform a 2139 // in generated code. If we succeed, there is no need to perform a
2128 // context lookup in the runtime system. 2140 // context lookup in the runtime system.
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
2227 MemOperand operand = EmitSlotSearch(slot, edx); 2239 MemOperand operand = EmitSlotSearch(slot, edx);
2228 __ mov(edx, operand); 2240 __ mov(edx, operand);
2229 2241
2230 ASSERT(prop->key()->AsLiteral() != NULL); 2242 ASSERT(prop->key()->AsLiteral() != NULL);
2231 ASSERT(prop->key()->AsLiteral()->handle()->IsSmi()); 2243 ASSERT(prop->key()->AsLiteral()->handle()->IsSmi());
2232 __ mov(eax, prop->key()->AsLiteral()->handle()); 2244 __ mov(eax, prop->key()->AsLiteral()->handle());
2233 2245
2234 // Record source code position for IC call. 2246 // Record source code position for IC call.
2235 SetSourcePosition(prop->position()); 2247 SetSourcePosition(prop->position());
2236 2248
2237 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); 2249 Handle<Code> ic(isolate()->builtins()->builtin(
2250 Builtins::KeyedLoadIC_Initialize));
2238 EmitCallIC(ic, RelocInfo::CODE_TARGET); 2251 EmitCallIC(ic, RelocInfo::CODE_TARGET);
2239 // Push result (function). 2252 // Push result (function).
2240 __ push(eax); 2253 __ push(eax);
2241 // Push Global receiver. 2254 // Push Global receiver.
2242 __ mov(ecx, GlobalObjectOperand()); 2255 __ mov(ecx, GlobalObjectOperand());
2243 __ push(FieldOperand(ecx, GlobalObject::kGlobalReceiverOffset)); 2256 __ push(FieldOperand(ecx, GlobalObject::kGlobalReceiverOffset));
2244 EmitCallWithStub(expr); 2257 EmitCallWithStub(expr);
2245 } else { 2258 } else {
2246 { PreservePositionScope scope(masm()->positions_recorder()); 2259 { PreservePositionScope scope(masm()->positions_recorder());
2247 VisitForStackValue(prop->obj()); 2260 VisitForStackValue(prop->obj());
2248 } 2261 }
2249 EmitKeyedCallWithIC(expr, prop->key(), RelocInfo::CODE_TARGET); 2262 EmitKeyedCallWithIC(expr, prop->key(), RelocInfo::CODE_TARGET);
2250 } 2263 }
2251 } 2264 }
2252 } else { 2265 } else {
2253 // Call to some other expression. If the expression is an anonymous 2266 // Call to some other expression. If the expression is an anonymous
2254 // function literal not called in a loop, mark it as one that should 2267 // function literal not called in a loop, mark it as one that should
2255 // also use the full code generator. 2268 // also use the full code generator.
2256 FunctionLiteral* lit = fun->AsFunctionLiteral(); 2269 FunctionLiteral* lit = fun->AsFunctionLiteral();
2257 if (lit != NULL && 2270 if (lit != NULL &&
2258 lit->name()->Equals(Heap::empty_string()) && 2271 lit->name()->Equals(isolate()->heap()->empty_string()) &&
2259 loop_depth() == 0) { 2272 loop_depth() == 0) {
2260 lit->set_try_full_codegen(true); 2273 lit->set_try_full_codegen(true);
2261 } 2274 }
2262 { PreservePositionScope scope(masm()->positions_recorder()); 2275 { PreservePositionScope scope(masm()->positions_recorder());
2263 VisitForStackValue(fun); 2276 VisitForStackValue(fun);
2264 } 2277 }
2265 // Load global receiver object. 2278 // Load global receiver object.
2266 __ mov(ebx, GlobalObjectOperand()); 2279 __ mov(ebx, GlobalObjectOperand());
2267 __ push(FieldOperand(ebx, GlobalObject::kGlobalReceiverOffset)); 2280 __ push(FieldOperand(ebx, GlobalObject::kGlobalReceiverOffset));
2268 // Emit function call. 2281 // Emit function call.
(...skipping 26 matching lines...) Expand all
2295 } 2308 }
2296 2309
2297 // Call the construct call builtin that handles allocation and 2310 // Call the construct call builtin that handles allocation and
2298 // constructor invocation. 2311 // constructor invocation.
2299 SetSourcePosition(expr->position()); 2312 SetSourcePosition(expr->position());
2300 2313
2301 // Load function and argument count into edi and eax. 2314 // Load function and argument count into edi and eax.
2302 __ Set(eax, Immediate(arg_count)); 2315 __ Set(eax, Immediate(arg_count));
2303 __ mov(edi, Operand(esp, arg_count * kPointerSize)); 2316 __ mov(edi, Operand(esp, arg_count * kPointerSize));
2304 2317
2305 Handle<Code> construct_builtin(Builtins::builtin(Builtins::JSConstructCall)); 2318 Handle<Code> construct_builtin(isolate()->builtins()->builtin(
2319 Builtins::JSConstructCall));
2306 __ call(construct_builtin, RelocInfo::CONSTRUCT_CALL); 2320 __ call(construct_builtin, RelocInfo::CONSTRUCT_CALL);
2307 context()->Plug(eax); 2321 context()->Plug(eax);
2308 } 2322 }
2309 2323
2310 2324
2311 void FullCodeGenerator::EmitIsSmi(ZoneList<Expression*>* args) { 2325 void FullCodeGenerator::EmitIsSmi(ZoneList<Expression*>* args) {
2312 ASSERT(args->length() == 1); 2326 ASSERT(args->length() == 1);
2313 2327
2314 VisitForAccumulatorValue(args->at(0)); 2328 VisitForAccumulatorValue(args->at(0));
2315 2329
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
2355 2369
2356 Label materialize_true, materialize_false; 2370 Label materialize_true, materialize_false;
2357 Label* if_true = NULL; 2371 Label* if_true = NULL;
2358 Label* if_false = NULL; 2372 Label* if_false = NULL;
2359 Label* fall_through = NULL; 2373 Label* fall_through = NULL;
2360 context()->PrepareTest(&materialize_true, &materialize_false, 2374 context()->PrepareTest(&materialize_true, &materialize_false,
2361 &if_true, &if_false, &fall_through); 2375 &if_true, &if_false, &fall_through);
2362 2376
2363 __ test(eax, Immediate(kSmiTagMask)); 2377 __ test(eax, Immediate(kSmiTagMask));
2364 __ j(zero, if_false); 2378 __ j(zero, if_false);
2365 __ cmp(eax, Factory::null_value()); 2379 __ cmp(eax, isolate()->factory()->null_value());
2366 __ j(equal, if_true); 2380 __ j(equal, if_true);
2367 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset)); 2381 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
2368 // Undetectable objects behave like undefined when tested with typeof. 2382 // Undetectable objects behave like undefined when tested with typeof.
2369 __ movzx_b(ecx, FieldOperand(ebx, Map::kBitFieldOffset)); 2383 __ movzx_b(ecx, FieldOperand(ebx, Map::kBitFieldOffset));
2370 __ test(ecx, Immediate(1 << Map::kIsUndetectable)); 2384 __ test(ecx, Immediate(1 << Map::kIsUndetectable));
2371 __ j(not_zero, if_false); 2385 __ j(not_zero, if_false);
2372 __ movzx_b(ecx, FieldOperand(ebx, Map::kInstanceTypeOffset)); 2386 __ movzx_b(ecx, FieldOperand(ebx, Map::kInstanceTypeOffset));
2373 __ cmp(ecx, FIRST_JS_OBJECT_TYPE); 2387 __ cmp(ecx, FIRST_JS_OBJECT_TYPE);
2374 __ j(below, if_false); 2388 __ j(below, if_false);
2375 __ cmp(ecx, LAST_JS_OBJECT_TYPE); 2389 __ cmp(ecx, LAST_JS_OBJECT_TYPE);
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after
2634 __ j(not_equal, &non_function_constructor); 2648 __ j(not_equal, &non_function_constructor);
2635 2649
2636 // eax now contains the constructor function. Grab the 2650 // eax now contains the constructor function. Grab the
2637 // instance class name from there. 2651 // instance class name from there.
2638 __ mov(eax, FieldOperand(eax, JSFunction::kSharedFunctionInfoOffset)); 2652 __ mov(eax, FieldOperand(eax, JSFunction::kSharedFunctionInfoOffset));
2639 __ mov(eax, FieldOperand(eax, SharedFunctionInfo::kInstanceClassNameOffset)); 2653 __ mov(eax, FieldOperand(eax, SharedFunctionInfo::kInstanceClassNameOffset));
2640 __ jmp(&done); 2654 __ jmp(&done);
2641 2655
2642 // Functions have class 'Function'. 2656 // Functions have class 'Function'.
2643 __ bind(&function); 2657 __ bind(&function);
2644 __ mov(eax, Factory::function_class_symbol()); 2658 __ mov(eax, isolate()->factory()->function_class_symbol());
2645 __ jmp(&done); 2659 __ jmp(&done);
2646 2660
2647 // Objects with a non-function constructor have class 'Object'. 2661 // Objects with a non-function constructor have class 'Object'.
2648 __ bind(&non_function_constructor); 2662 __ bind(&non_function_constructor);
2649 __ mov(eax, Factory::Object_symbol()); 2663 __ mov(eax, isolate()->factory()->Object_symbol());
2650 __ jmp(&done); 2664 __ jmp(&done);
2651 2665
2652 // Non-JS objects have class null. 2666 // Non-JS objects have class null.
2653 __ bind(&null); 2667 __ bind(&null);
2654 __ mov(eax, Factory::null_value()); 2668 __ mov(eax, isolate()->factory()->null_value());
2655 2669
2656 // All done. 2670 // All done.
2657 __ bind(&done); 2671 __ bind(&done);
2658 2672
2659 context()->Plug(eax); 2673 context()->Plug(eax);
2660 } 2674 }
2661 2675
2662 2676
2663 void FullCodeGenerator::EmitLog(ZoneList<Expression*>* args) { 2677 void FullCodeGenerator::EmitLog(ZoneList<Expression*>* args) {
2664 // Conditionally generate a log call. 2678 // Conditionally generate a log call.
2665 // Args: 2679 // Args:
2666 // 0 (literal string): The type of logging (corresponds to the flags). 2680 // 0 (literal string): The type of logging (corresponds to the flags).
2667 // This is used to determine whether or not to generate the log call. 2681 // This is used to determine whether or not to generate the log call.
2668 // 1 (string): Format string. Access the string at argument index 2 2682 // 1 (string): Format string. Access the string at argument index 2
2669 // with '%2s' (see Logger::LogRuntime for all the formats). 2683 // with '%2s' (see Logger::LogRuntime for all the formats).
2670 // 2 (array): Arguments to the format string. 2684 // 2 (array): Arguments to the format string.
2671 ASSERT_EQ(args->length(), 3); 2685 ASSERT_EQ(args->length(), 3);
2672 #ifdef ENABLE_LOGGING_AND_PROFILING 2686 #ifdef ENABLE_LOGGING_AND_PROFILING
2673 if (CodeGenerator::ShouldGenerateLog(args->at(0))) { 2687 if (CodeGenerator::ShouldGenerateLog(args->at(0))) {
2674 VisitForStackValue(args->at(1)); 2688 VisitForStackValue(args->at(1));
2675 VisitForStackValue(args->at(2)); 2689 VisitForStackValue(args->at(2));
2676 __ CallRuntime(Runtime::kLog, 2); 2690 __ CallRuntime(Runtime::kLog, 2);
2677 } 2691 }
2678 #endif 2692 #endif
2679 // Finally, we're expected to leave a value on the top of the stack. 2693 // Finally, we're expected to leave a value on the top of the stack.
2680 __ mov(eax, Factory::undefined_value()); 2694 __ mov(eax, isolate()->factory()->undefined_value());
2681 context()->Plug(eax); 2695 context()->Plug(eax);
2682 } 2696 }
2683 2697
2684 2698
2685 void FullCodeGenerator::EmitRandomHeapNumber(ZoneList<Expression*>* args) { 2699 void FullCodeGenerator::EmitRandomHeapNumber(ZoneList<Expression*>* args) {
2686 ASSERT(args->length() == 0); 2700 ASSERT(args->length() == 0);
2687 2701
2688 Label slow_allocate_heapnumber; 2702 Label slow_allocate_heapnumber;
2689 Label heapnumber_allocated; 2703 Label heapnumber_allocated;
2690 2704
2691 __ AllocateHeapNumber(edi, ebx, ecx, &slow_allocate_heapnumber); 2705 __ AllocateHeapNumber(edi, ebx, ecx, &slow_allocate_heapnumber);
2692 __ jmp(&heapnumber_allocated); 2706 __ jmp(&heapnumber_allocated);
2693 2707
2694 __ bind(&slow_allocate_heapnumber); 2708 __ bind(&slow_allocate_heapnumber);
2695 // Allocate a heap number. 2709 // Allocate a heap number.
2696 __ CallRuntime(Runtime::kNumberAlloc, 0); 2710 __ CallRuntime(Runtime::kNumberAlloc, 0);
2697 __ mov(edi, eax); 2711 __ mov(edi, eax);
2698 2712
2699 __ bind(&heapnumber_allocated); 2713 __ bind(&heapnumber_allocated);
2700 2714
2701 __ PrepareCallCFunction(0, ebx); 2715 __ PrepareCallCFunction(0, ebx);
2702 __ CallCFunction(ExternalReference::random_uint32_function(), 0); 2716 __ CallCFunction(ExternalReference::random_uint32_function(), 0);
2703 2717
2704 // Convert 32 random bits in eax to 0.(32 random bits) in a double 2718 // Convert 32 random bits in eax to 0.(32 random bits) in a double
2705 // by computing: 2719 // by computing:
2706 // ( 1.(20 0s)(32 random bits) x 2^20 ) - (1.0 x 2^20)). 2720 // ( 1.(20 0s)(32 random bits) x 2^20 ) - (1.0 x 2^20)).
2707 // This is implemented on both SSE2 and FPU. 2721 // This is implemented on both SSE2 and FPU.
2708 if (CpuFeatures::IsSupported(SSE2)) { 2722 if (isolate()->cpu_features()->IsSupported(SSE2)) {
2709 CpuFeatures::Scope fscope(SSE2); 2723 CpuFeatures::Scope fscope(SSE2);
2710 __ mov(ebx, Immediate(0x49800000)); // 1.0 x 2^20 as single. 2724 __ mov(ebx, Immediate(0x49800000)); // 1.0 x 2^20 as single.
2711 __ movd(xmm1, Operand(ebx)); 2725 __ movd(xmm1, Operand(ebx));
2712 __ movd(xmm0, Operand(eax)); 2726 __ movd(xmm0, Operand(eax));
2713 __ cvtss2sd(xmm1, xmm1); 2727 __ cvtss2sd(xmm1, xmm1);
2714 __ pxor(xmm0, xmm1); 2728 __ pxor(xmm0, xmm1);
2715 __ subsd(xmm0, xmm1); 2729 __ subsd(xmm0, xmm1);
2716 __ movdbl(FieldOperand(edi, HeapNumber::kValueOffset), xmm0); 2730 __ movdbl(FieldOperand(edi, HeapNumber::kValueOffset), xmm0);
2717 } else { 2731 } else {
2718 // 0x4130000000000000 is 1.0 x 2^20 as a double. 2732 // 0x4130000000000000 is 1.0 x 2^20 as a double.
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
2868 &need_conversion, 2882 &need_conversion,
2869 &need_conversion, 2883 &need_conversion,
2870 &index_out_of_range, 2884 &index_out_of_range,
2871 STRING_INDEX_IS_NUMBER); 2885 STRING_INDEX_IS_NUMBER);
2872 generator.GenerateFast(masm_); 2886 generator.GenerateFast(masm_);
2873 __ jmp(&done); 2887 __ jmp(&done);
2874 2888
2875 __ bind(&index_out_of_range); 2889 __ bind(&index_out_of_range);
2876 // When the index is out of range, the spec requires us to return 2890 // When the index is out of range, the spec requires us to return
2877 // NaN. 2891 // NaN.
2878 __ Set(result, Immediate(Factory::nan_value())); 2892 __ Set(result, Immediate(isolate()->factory()->nan_value()));
2879 __ jmp(&done); 2893 __ jmp(&done);
2880 2894
2881 __ bind(&need_conversion); 2895 __ bind(&need_conversion);
2882 // Move the undefined value into the result register, which will 2896 // Move the undefined value into the result register, which will
2883 // trigger conversion. 2897 // trigger conversion.
2884 __ Set(result, Immediate(Factory::undefined_value())); 2898 __ Set(result, Immediate(isolate()->factory()->undefined_value()));
2885 __ jmp(&done); 2899 __ jmp(&done);
2886 2900
2887 NopRuntimeCallHelper call_helper; 2901 NopRuntimeCallHelper call_helper;
2888 generator.GenerateSlow(masm_, call_helper); 2902 generator.GenerateSlow(masm_, call_helper);
2889 2903
2890 __ bind(&done); 2904 __ bind(&done);
2891 context()->Plug(result); 2905 context()->Plug(result);
2892 } 2906 }
2893 2907
2894 2908
(...skipping 22 matching lines...) Expand all
2917 &need_conversion, 2931 &need_conversion,
2918 &need_conversion, 2932 &need_conversion,
2919 &index_out_of_range, 2933 &index_out_of_range,
2920 STRING_INDEX_IS_NUMBER); 2934 STRING_INDEX_IS_NUMBER);
2921 generator.GenerateFast(masm_); 2935 generator.GenerateFast(masm_);
2922 __ jmp(&done); 2936 __ jmp(&done);
2923 2937
2924 __ bind(&index_out_of_range); 2938 __ bind(&index_out_of_range);
2925 // When the index is out of range, the spec requires us to return 2939 // When the index is out of range, the spec requires us to return
2926 // the empty string. 2940 // the empty string.
2927 __ Set(result, Immediate(Factory::empty_string())); 2941 __ Set(result, Immediate(isolate()->factory()->empty_string()));
2928 __ jmp(&done); 2942 __ jmp(&done);
2929 2943
2930 __ bind(&need_conversion); 2944 __ bind(&need_conversion);
2931 // Move smi zero into the result register, which will trigger 2945 // Move smi zero into the result register, which will trigger
2932 // conversion. 2946 // conversion.
2933 __ Set(result, Immediate(Smi::FromInt(0))); 2947 __ Set(result, Immediate(Smi::FromInt(0)));
2934 __ jmp(&done); 2948 __ jmp(&done);
2935 2949
2936 NopRuntimeCallHelper call_helper; 2950 NopRuntimeCallHelper call_helper;
2937 generator.GenerateSlow(masm_, call_helper); 2951 generator.GenerateSlow(masm_, call_helper);
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
3056 // has no indexed interceptor. 3070 // has no indexed interceptor.
3057 __ CmpObjectType(object, JS_ARRAY_TYPE, temp); 3071 __ CmpObjectType(object, JS_ARRAY_TYPE, temp);
3058 __ j(not_equal, &slow_case); 3072 __ j(not_equal, &slow_case);
3059 __ test_b(FieldOperand(temp, Map::kBitFieldOffset), 3073 __ test_b(FieldOperand(temp, Map::kBitFieldOffset),
3060 KeyedLoadIC::kSlowCaseBitFieldMask); 3074 KeyedLoadIC::kSlowCaseBitFieldMask);
3061 __ j(not_zero, &slow_case); 3075 __ j(not_zero, &slow_case);
3062 3076
3063 // Check the object's elements are in fast case and writable. 3077 // Check the object's elements are in fast case and writable.
3064 __ mov(elements, FieldOperand(object, JSObject::kElementsOffset)); 3078 __ mov(elements, FieldOperand(object, JSObject::kElementsOffset));
3065 __ cmp(FieldOperand(elements, HeapObject::kMapOffset), 3079 __ cmp(FieldOperand(elements, HeapObject::kMapOffset),
3066 Immediate(Factory::fixed_array_map())); 3080 Immediate(isolate()->factory()->fixed_array_map()));
3067 __ j(not_equal, &slow_case); 3081 __ j(not_equal, &slow_case);
3068 3082
3069 // Check that both indices are smis. 3083 // Check that both indices are smis.
3070 __ mov(index_1, Operand(esp, 1 * kPointerSize)); 3084 __ mov(index_1, Operand(esp, 1 * kPointerSize));
3071 __ mov(index_2, Operand(esp, 0)); 3085 __ mov(index_2, Operand(esp, 0));
3072 __ mov(temp, index_1); 3086 __ mov(temp, index_1);
3073 __ or_(temp, Operand(index_2)); 3087 __ or_(temp, Operand(index_2));
3074 __ test(temp, Immediate(kSmiTagMask)); 3088 __ test(temp, Immediate(kSmiTagMask));
3075 __ j(not_zero, &slow_case); 3089 __ j(not_zero, &slow_case);
3076 3090
(...skipping 21 matching lines...) Expand all
3098 // Since we are swapping two objects, the incremental marker is not disturbed, 3112 // Since we are swapping two objects, the incremental marker is not disturbed,
3099 // so we don't call the stub that handles this. TODO(gc): Optimize by 3113 // so we don't call the stub that handles this. TODO(gc): Optimize by
3100 // checking the scan_on_scavenge flag, probably by calling the stub. 3114 // checking the scan_on_scavenge flag, probably by calling the stub.
3101 __ RememberedSetHelper(object, index_1, temp, kDontSaveFPRegs); 3115 __ RememberedSetHelper(object, index_1, temp, kDontSaveFPRegs);
3102 __ RememberedSetHelper(elements, index_2, temp, kDontSaveFPRegs); 3116 __ RememberedSetHelper(elements, index_2, temp, kDontSaveFPRegs);
3103 3117
3104 __ bind(&new_space); 3118 __ bind(&new_space);
3105 3119
3106 // We are done. Drop elements from the stack, and return undefined. 3120 // We are done. Drop elements from the stack, and return undefined.
3107 __ add(Operand(esp), Immediate(3 * kPointerSize)); 3121 __ add(Operand(esp), Immediate(3 * kPointerSize));
3108 __ mov(eax, Factory::undefined_value()); 3122 __ mov(eax, isolate()->factory()->undefined_value());
3109 __ jmp(&done); 3123 __ jmp(&done);
3110 3124
3111 __ bind(&slow_case); 3125 __ bind(&slow_case);
3112 __ CallRuntime(Runtime::kSwapElements, 3); 3126 __ CallRuntime(Runtime::kSwapElements, 3);
3113 3127
3114 __ bind(&done); 3128 __ bind(&done);
3115 context()->Plug(eax); 3129 context()->Plug(eax);
3116 } 3130 }
3117 3131
3118 3132
3119 void FullCodeGenerator::EmitGetFromCache(ZoneList<Expression*>* args) { 3133 void FullCodeGenerator::EmitGetFromCache(ZoneList<Expression*>* args) {
3120 ASSERT_EQ(2, args->length()); 3134 ASSERT_EQ(2, args->length());
3121 3135
3122 ASSERT_NE(NULL, args->at(0)->AsLiteral()); 3136 ASSERT_NE(NULL, args->at(0)->AsLiteral());
3123 int cache_id = Smi::cast(*(args->at(0)->AsLiteral()->handle()))->value(); 3137 int cache_id = Smi::cast(*(args->at(0)->AsLiteral()->handle()))->value();
3124 3138
3125 Handle<FixedArray> jsfunction_result_caches( 3139 Handle<FixedArray> jsfunction_result_caches(
3126 Top::global_context()->jsfunction_result_caches()); 3140 isolate()->global_context()->jsfunction_result_caches());
3127 if (jsfunction_result_caches->length() <= cache_id) { 3141 if (jsfunction_result_caches->length() <= cache_id) {
3128 __ Abort("Attempt to use undefined cache."); 3142 __ Abort("Attempt to use undefined cache.");
3129 __ mov(eax, Factory::undefined_value()); 3143 __ mov(eax, isolate()->factory()->undefined_value());
3130 context()->Plug(eax); 3144 context()->Plug(eax);
3131 return; 3145 return;
3132 } 3146 }
3133 3147
3134 VisitForAccumulatorValue(args->at(1)); 3148 VisitForAccumulatorValue(args->at(1));
3135 3149
3136 Register key = eax; 3150 Register key = eax;
3137 Register cache = ebx; 3151 Register cache = ebx;
3138 Register tmp = ecx; 3152 Register tmp = ecx;
3139 __ mov(cache, ContextOperand(esi, Context::GLOBAL_INDEX)); 3153 __ mov(cache, ContextOperand(esi, Context::GLOBAL_INDEX));
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
3176 __ pop(left); 3190 __ pop(left);
3177 3191
3178 Label done, fail, ok; 3192 Label done, fail, ok;
3179 __ cmp(left, Operand(right)); 3193 __ cmp(left, Operand(right));
3180 __ j(equal, &ok); 3194 __ j(equal, &ok);
3181 // Fail if either is a non-HeapObject. 3195 // Fail if either is a non-HeapObject.
3182 __ mov(tmp, left); 3196 __ mov(tmp, left);
3183 __ and_(Operand(tmp), right); 3197 __ and_(Operand(tmp), right);
3184 __ test(Operand(tmp), Immediate(kSmiTagMask)); 3198 __ test(Operand(tmp), Immediate(kSmiTagMask));
3185 __ j(zero, &fail); 3199 __ j(zero, &fail);
3186 __ CmpObjectType(left, JS_REGEXP_TYPE, tmp); 3200 __ mov(tmp, FieldOperand(left, HeapObject::kMapOffset));
3201 __ CmpInstanceType(tmp, JS_REGEXP_TYPE);
3187 __ j(not_equal, &fail); 3202 __ j(not_equal, &fail);
3188 __ cmp(tmp, FieldOperand(right, HeapObject::kMapOffset)); 3203 __ cmp(tmp, FieldOperand(right, HeapObject::kMapOffset));
3189 __ j(not_equal, &fail); 3204 __ j(not_equal, &fail);
3190 __ mov(tmp, FieldOperand(left, JSRegExp::kDataOffset)); 3205 __ mov(tmp, FieldOperand(left, JSRegExp::kDataOffset));
3191 __ cmp(tmp, FieldOperand(right, JSRegExp::kDataOffset)); 3206 __ cmp(tmp, FieldOperand(right, JSRegExp::kDataOffset));
3192 __ j(equal, &ok); 3207 __ j(equal, &ok);
3193 __ bind(&fail); 3208 __ bind(&fail);
3194 __ mov(eax, Immediate(Factory::false_value())); 3209 __ mov(eax, Immediate(isolate()->factory()->false_value()));
3195 __ jmp(&done); 3210 __ jmp(&done);
3196 __ bind(&ok); 3211 __ bind(&ok);
3197 __ mov(eax, Immediate(Factory::true_value())); 3212 __ mov(eax, Immediate(isolate()->factory()->true_value()));
3198 __ bind(&done); 3213 __ bind(&done);
3199 3214
3200 context()->Plug(eax); 3215 context()->Plug(eax);
3201 } 3216 }
3202 3217
3203 3218
3204 void FullCodeGenerator::EmitHasCachedArrayIndex(ZoneList<Expression*>* args) { 3219 void FullCodeGenerator::EmitHasCachedArrayIndex(ZoneList<Expression*>* args) {
3205 ASSERT(args->length() == 1); 3220 ASSERT(args->length() == 1);
3206 3221
3207 VisitForAccumulatorValue(args->at(0)); 3222 VisitForAccumulatorValue(args->at(0));
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
3280 3295
3281 // Check that the array has fast elements. 3296 // Check that the array has fast elements.
3282 __ test_b(FieldOperand(scratch, Map::kBitField2Offset), 3297 __ test_b(FieldOperand(scratch, Map::kBitField2Offset),
3283 1 << Map::kHasFastElements); 3298 1 << Map::kHasFastElements);
3284 __ j(zero, &bailout); 3299 __ j(zero, &bailout);
3285 3300
3286 // If the array has length zero, return the empty string. 3301 // If the array has length zero, return the empty string.
3287 __ mov(array_length, FieldOperand(array, JSArray::kLengthOffset)); 3302 __ mov(array_length, FieldOperand(array, JSArray::kLengthOffset));
3288 __ SmiUntag(array_length); 3303 __ SmiUntag(array_length);
3289 __ j(not_zero, &non_trivial_array); 3304 __ j(not_zero, &non_trivial_array);
3290 __ mov(result_operand, Factory::empty_string()); 3305 __ mov(result_operand, FACTORY->empty_string());
3291 __ jmp(&done); 3306 __ jmp(&done);
3292 3307
3293 // Save the array length. 3308 // Save the array length.
3294 __ bind(&non_trivial_array); 3309 __ bind(&non_trivial_array);
3295 __ mov(array_length_operand, array_length); 3310 __ mov(array_length_operand, array_length);
3296 3311
3297 // Save the FixedArray containing array's elements. 3312 // Save the FixedArray containing array's elements.
3298 // End of array's live range. 3313 // End of array's live range.
3299 elements = array; 3314 elements = array;
3300 __ mov(elements, FieldOperand(array, JSArray::kElementsOffset)); 3315 __ mov(elements, FieldOperand(array, JSArray::kElementsOffset));
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
3491 FieldOperand(string, SeqAsciiString::kHeaderSize)); 3506 FieldOperand(string, SeqAsciiString::kHeaderSize));
3492 __ CopyBytes(string, result_pos, string_length, scratch); 3507 __ CopyBytes(string, result_pos, string_length, scratch);
3493 __ add(Operand(index), Immediate(1)); 3508 __ add(Operand(index), Immediate(1));
3494 3509
3495 __ cmp(index, array_length_operand); 3510 __ cmp(index, array_length_operand);
3496 __ j(less, &loop_3); // End while (index < length). 3511 __ j(less, &loop_3); // End while (index < length).
3497 __ jmp(&done); 3512 __ jmp(&done);
3498 3513
3499 3514
3500 __ bind(&bailout); 3515 __ bind(&bailout);
3501 __ mov(result_operand, Factory::undefined_value()); 3516 __ mov(result_operand, FACTORY->undefined_value());
3502 __ bind(&done); 3517 __ bind(&done);
3503 __ mov(eax, result_operand); 3518 __ mov(eax, result_operand);
3504 // Drop temp values from the stack, and restore context register. 3519 // Drop temp values from the stack, and restore context register.
3505 __ add(Operand(esp), Immediate(3 * kPointerSize)); 3520 __ add(Operand(esp), Immediate(3 * kPointerSize));
3506 3521
3507 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 3522 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
3508 context()->Plug(eax); 3523 context()->Plug(eax);
3509 } 3524 }
3510 3525
3511 3526
(...skipping 17 matching lines...) Expand all
3529 // Push the arguments ("left-to-right"). 3544 // Push the arguments ("left-to-right").
3530 int arg_count = args->length(); 3545 int arg_count = args->length();
3531 for (int i = 0; i < arg_count; i++) { 3546 for (int i = 0; i < arg_count; i++) {
3532 VisitForStackValue(args->at(i)); 3547 VisitForStackValue(args->at(i));
3533 } 3548 }
3534 3549
3535 if (expr->is_jsruntime()) { 3550 if (expr->is_jsruntime()) {
3536 // Call the JS runtime function via a call IC. 3551 // Call the JS runtime function via a call IC.
3537 __ Set(ecx, Immediate(expr->name())); 3552 __ Set(ecx, Immediate(expr->name()));
3538 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; 3553 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
3539 Handle<Code> ic = StubCache::ComputeCallInitialize(arg_count, in_loop); 3554 Handle<Code> ic = isolate()->stub_cache()->ComputeCallInitialize(
3555 arg_count, in_loop);
3540 EmitCallIC(ic, RelocInfo::CODE_TARGET); 3556 EmitCallIC(ic, RelocInfo::CODE_TARGET);
3541 // Restore context register. 3557 // Restore context register.
3542 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 3558 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
3543 } else { 3559 } else {
3544 // Call the C runtime function. 3560 // Call the C runtime function.
3545 __ CallRuntime(expr->function(), arg_count); 3561 __ CallRuntime(expr->function(), arg_count);
3546 } 3562 }
3547 context()->Plug(eax); 3563 context()->Plug(eax);
3548 } 3564 }
3549 3565
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
3595 // The subexpression may have side effects. 3611 // The subexpression may have side effects.
3596 VisitForEffect(expr->expression()); 3612 VisitForEffect(expr->expression());
3597 context()->Plug(true); 3613 context()->Plug(true);
3598 } 3614 }
3599 break; 3615 break;
3600 } 3616 }
3601 3617
3602 case Token::VOID: { 3618 case Token::VOID: {
3603 Comment cmnt(masm_, "[ UnaryOperation (VOID)"); 3619 Comment cmnt(masm_, "[ UnaryOperation (VOID)");
3604 VisitForEffect(expr->expression()); 3620 VisitForEffect(expr->expression());
3605 context()->Plug(Factory::undefined_value()); 3621 context()->Plug(isolate()->factory()->undefined_value());
3606 break; 3622 break;
3607 } 3623 }
3608 3624
3609 case Token::NOT: { 3625 case Token::NOT: {
3610 Comment cmnt(masm_, "[ UnaryOperation (NOT)"); 3626 Comment cmnt(masm_, "[ UnaryOperation (NOT)");
3611 if (context()->IsEffect()) { 3627 if (context()->IsEffect()) {
3612 // Unary NOT has no side effects so it's only necessary to visit the 3628 // Unary NOT has no side effects so it's only necessary to visit the
3613 // subexpression. Match the optimizing compiler by not branching. 3629 // subexpression. Match the optimizing compiler by not branching.
3614 VisitForEffect(expr->expression()); 3630 VisitForEffect(expr->expression());
3615 } else { 3631 } else {
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
3843 // Perform the assignment as if via '='. 3859 // Perform the assignment as if via '='.
3844 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 3860 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
3845 Token::ASSIGN); 3861 Token::ASSIGN);
3846 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3862 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3847 context()->Plug(eax); 3863 context()->Plug(eax);
3848 } 3864 }
3849 break; 3865 break;
3850 case NAMED_PROPERTY: { 3866 case NAMED_PROPERTY: {
3851 __ mov(ecx, prop->key()->AsLiteral()->handle()); 3867 __ mov(ecx, prop->key()->AsLiteral()->handle());
3852 __ pop(edx); 3868 __ pop(edx);
3853 Handle<Code> ic(Builtins::builtin( 3869 Handle<Code> ic(isolate()->builtins()->builtin(
3854 is_strict_mode() ? Builtins::StoreIC_Initialize_Strict 3870 is_strict_mode() ? Builtins::StoreIC_Initialize_Strict
3855 : Builtins::StoreIC_Initialize)); 3871 : Builtins::StoreIC_Initialize));
3856 EmitCallIC(ic, RelocInfo::CODE_TARGET); 3872 EmitCallIC(ic, RelocInfo::CODE_TARGET);
3857 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3873 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3858 if (expr->is_postfix()) { 3874 if (expr->is_postfix()) {
3859 if (!context()->IsEffect()) { 3875 if (!context()->IsEffect()) {
3860 context()->PlugTOS(); 3876 context()->PlugTOS();
3861 } 3877 }
3862 } else { 3878 } else {
3863 context()->Plug(eax); 3879 context()->Plug(eax);
3864 } 3880 }
3865 break; 3881 break;
3866 } 3882 }
3867 case KEYED_PROPERTY: { 3883 case KEYED_PROPERTY: {
3868 __ pop(ecx); 3884 __ pop(ecx);
3869 __ pop(edx); 3885 __ pop(edx);
3870 Handle<Code> ic(Builtins::builtin( 3886 Handle<Code> ic(isolate()->builtins()->builtin(
3871 is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict 3887 is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict
3872 : Builtins::KeyedStoreIC_Initialize)); 3888 : Builtins::KeyedStoreIC_Initialize));
3873 EmitCallIC(ic, RelocInfo::CODE_TARGET); 3889 EmitCallIC(ic, RelocInfo::CODE_TARGET);
3874 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3890 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3875 if (expr->is_postfix()) { 3891 if (expr->is_postfix()) {
3876 // Result is on the stack 3892 // Result is on the stack
3877 if (!context()->IsEffect()) { 3893 if (!context()->IsEffect()) {
3878 context()->PlugTOS(); 3894 context()->PlugTOS();
3879 } 3895 }
3880 } else { 3896 } else {
3881 context()->Plug(eax); 3897 context()->Plug(eax);
3882 } 3898 }
3883 break; 3899 break;
3884 } 3900 }
3885 } 3901 }
3886 } 3902 }
3887 3903
3888 3904
3889 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { 3905 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) {
3890 VariableProxy* proxy = expr->AsVariableProxy(); 3906 VariableProxy* proxy = expr->AsVariableProxy();
3891 ASSERT(!context()->IsEffect()); 3907 ASSERT(!context()->IsEffect());
3892 ASSERT(!context()->IsTest()); 3908 ASSERT(!context()->IsTest());
3893 3909
3894 if (proxy != NULL && !proxy->var()->is_this() && proxy->var()->is_global()) { 3910 if (proxy != NULL && !proxy->var()->is_this() && proxy->var()->is_global()) {
3895 Comment cmnt(masm_, "Global variable"); 3911 Comment cmnt(masm_, "Global variable");
3896 __ mov(eax, GlobalObjectOperand()); 3912 __ mov(eax, GlobalObjectOperand());
3897 __ mov(ecx, Immediate(proxy->name())); 3913 __ mov(ecx, Immediate(proxy->name()));
3898 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); 3914 Handle<Code> ic(isolate()->builtins()->builtin(
3915 Builtins::LoadIC_Initialize));
3899 // Use a regular load, not a contextual load, to avoid a reference 3916 // Use a regular load, not a contextual load, to avoid a reference
3900 // error. 3917 // error.
3901 EmitCallIC(ic, RelocInfo::CODE_TARGET); 3918 EmitCallIC(ic, RelocInfo::CODE_TARGET);
3902 PrepareForBailout(expr, TOS_REG); 3919 PrepareForBailout(expr, TOS_REG);
3903 context()->Plug(eax); 3920 context()->Plug(eax);
3904 } else if (proxy != NULL && 3921 } else if (proxy != NULL &&
3905 proxy->var()->AsSlot() != NULL && 3922 proxy->var()->AsSlot() != NULL &&
3906 proxy->var()->AsSlot()->type() == Slot::LOOKUP) { 3923 proxy->var()->AsSlot()->type() == Slot::LOOKUP) {
3907 Label done, slow; 3924 Label done, slow;
3908 3925
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
3941 if (!right_literal_value->IsString()) return false; 3958 if (!right_literal_value->IsString()) return false;
3942 UnaryOperation* left_unary = left->AsUnaryOperation(); 3959 UnaryOperation* left_unary = left->AsUnaryOperation();
3943 if (left_unary == NULL || left_unary->op() != Token::TYPEOF) return false; 3960 if (left_unary == NULL || left_unary->op() != Token::TYPEOF) return false;
3944 Handle<String> check = Handle<String>::cast(right_literal_value); 3961 Handle<String> check = Handle<String>::cast(right_literal_value);
3945 3962
3946 { AccumulatorValueContext context(this); 3963 { AccumulatorValueContext context(this);
3947 VisitForTypeofValue(left_unary->expression()); 3964 VisitForTypeofValue(left_unary->expression());
3948 } 3965 }
3949 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); 3966 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
3950 3967
3951 if (check->Equals(Heap::number_symbol())) { 3968 if (check->Equals(isolate()->heap()->number_symbol())) {
3952 __ JumpIfSmi(eax, if_true); 3969 __ JumpIfSmi(eax, if_true);
3953 __ cmp(FieldOperand(eax, HeapObject::kMapOffset), 3970 __ cmp(FieldOperand(eax, HeapObject::kMapOffset),
3954 Factory::heap_number_map()); 3971 isolate()->factory()->heap_number_map());
3955 Split(equal, if_true, if_false, fall_through); 3972 Split(equal, if_true, if_false, fall_through);
3956 } else if (check->Equals(Heap::string_symbol())) { 3973 } else if (check->Equals(isolate()->heap()->string_symbol())) {
3957 __ JumpIfSmi(eax, if_false); 3974 __ JumpIfSmi(eax, if_false);
3958 __ CmpObjectType(eax, FIRST_NONSTRING_TYPE, edx); 3975 __ CmpObjectType(eax, FIRST_NONSTRING_TYPE, edx);
3959 __ j(above_equal, if_false); 3976 __ j(above_equal, if_false);
3960 // Check for undetectable objects => false. 3977 // Check for undetectable objects => false.
3961 __ test_b(FieldOperand(edx, Map::kBitFieldOffset), 3978 __ test_b(FieldOperand(edx, Map::kBitFieldOffset),
3962 1 << Map::kIsUndetectable); 3979 1 << Map::kIsUndetectable);
3963 Split(zero, if_true, if_false, fall_through); 3980 Split(zero, if_true, if_false, fall_through);
3964 } else if (check->Equals(Heap::boolean_symbol())) { 3981 } else if (check->Equals(isolate()->heap()->boolean_symbol())) {
3965 __ cmp(eax, Factory::true_value()); 3982 __ cmp(eax, isolate()->factory()->true_value());
3966 __ j(equal, if_true); 3983 __ j(equal, if_true);
3967 __ cmp(eax, Factory::false_value()); 3984 __ cmp(eax, isolate()->factory()->false_value());
3968 Split(equal, if_true, if_false, fall_through); 3985 Split(equal, if_true, if_false, fall_through);
3969 } else if (check->Equals(Heap::undefined_symbol())) { 3986 } else if (check->Equals(isolate()->heap()->undefined_symbol())) {
3970 __ cmp(eax, Factory::undefined_value()); 3987 __ cmp(eax, isolate()->factory()->undefined_value());
3971 __ j(equal, if_true); 3988 __ j(equal, if_true);
3972 __ JumpIfSmi(eax, if_false); 3989 __ JumpIfSmi(eax, if_false);
3973 // Check for undetectable objects => true. 3990 // Check for undetectable objects => true.
3974 __ mov(edx, FieldOperand(eax, HeapObject::kMapOffset)); 3991 __ mov(edx, FieldOperand(eax, HeapObject::kMapOffset));
3975 __ movzx_b(ecx, FieldOperand(edx, Map::kBitFieldOffset)); 3992 __ movzx_b(ecx, FieldOperand(edx, Map::kBitFieldOffset));
3976 __ test(ecx, Immediate(1 << Map::kIsUndetectable)); 3993 __ test(ecx, Immediate(1 << Map::kIsUndetectable));
3977 Split(not_zero, if_true, if_false, fall_through); 3994 Split(not_zero, if_true, if_false, fall_through);
3978 } else if (check->Equals(Heap::function_symbol())) { 3995 } else if (check->Equals(isolate()->heap()->function_symbol())) {
3979 __ JumpIfSmi(eax, if_false); 3996 __ JumpIfSmi(eax, if_false);
3980 __ CmpObjectType(eax, FIRST_FUNCTION_CLASS_TYPE, edx); 3997 __ CmpObjectType(eax, FIRST_FUNCTION_CLASS_TYPE, edx);
3981 Split(above_equal, if_true, if_false, fall_through); 3998 Split(above_equal, if_true, if_false, fall_through);
3982 } else if (check->Equals(Heap::object_symbol())) { 3999 } else if (check->Equals(isolate()->heap()->object_symbol())) {
3983 __ JumpIfSmi(eax, if_false); 4000 __ JumpIfSmi(eax, if_false);
3984 __ cmp(eax, Factory::null_value()); 4001 __ cmp(eax, isolate()->factory()->null_value());
3985 __ j(equal, if_true); 4002 __ j(equal, if_true);
3986 __ CmpObjectType(eax, FIRST_JS_OBJECT_TYPE, edx); 4003 __ CmpObjectType(eax, FIRST_JS_OBJECT_TYPE, edx);
3987 __ j(below, if_false); 4004 __ j(below, if_false);
3988 __ CmpInstanceType(edx, FIRST_FUNCTION_CLASS_TYPE); 4005 __ CmpInstanceType(edx, FIRST_FUNCTION_CLASS_TYPE);
3989 __ j(above_equal, if_false); 4006 __ j(above_equal, if_false);
3990 // Check for undetectable objects => false. 4007 // Check for undetectable objects => false.
3991 __ test_b(FieldOperand(edx, Map::kBitFieldOffset), 4008 __ test_b(FieldOperand(edx, Map::kBitFieldOffset),
3992 1 << Map::kIsUndetectable); 4009 1 << Map::kIsUndetectable);
3993 Split(zero, if_true, if_false, fall_through); 4010 Split(zero, if_true, if_false, fall_through);
3994 } else { 4011 } else {
(...skipping 27 matching lines...) Expand all
4022 context()->Plug(if_true, if_false); 4039 context()->Plug(if_true, if_false);
4023 return; 4040 return;
4024 } 4041 }
4025 4042
4026 VisitForStackValue(expr->left()); 4043 VisitForStackValue(expr->left());
4027 switch (expr->op()) { 4044 switch (expr->op()) {
4028 case Token::IN: 4045 case Token::IN:
4029 VisitForStackValue(expr->right()); 4046 VisitForStackValue(expr->right());
4030 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION); 4047 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION);
4031 PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL); 4048 PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL);
4032 __ cmp(eax, Factory::true_value()); 4049 __ cmp(eax, isolate()->factory()->true_value());
4033 Split(equal, if_true, if_false, fall_through); 4050 Split(equal, if_true, if_false, fall_through);
4034 break; 4051 break;
4035 4052
4036 case Token::INSTANCEOF: { 4053 case Token::INSTANCEOF: {
4037 VisitForStackValue(expr->right()); 4054 VisitForStackValue(expr->right());
4038 InstanceofStub stub(InstanceofStub::kNoFlags); 4055 InstanceofStub stub(InstanceofStub::kNoFlags);
4039 __ CallStub(&stub); 4056 __ CallStub(&stub);
4040 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); 4057 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
4041 __ test(eax, Operand(eax)); 4058 __ test(eax, Operand(eax));
4042 // The stub returns 0 for true. 4059 // The stub returns 0 for true.
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
4115 Label materialize_true, materialize_false; 4132 Label materialize_true, materialize_false;
4116 Label* if_true = NULL; 4133 Label* if_true = NULL;
4117 Label* if_false = NULL; 4134 Label* if_false = NULL;
4118 Label* fall_through = NULL; 4135 Label* fall_through = NULL;
4119 context()->PrepareTest(&materialize_true, &materialize_false, 4136 context()->PrepareTest(&materialize_true, &materialize_false,
4120 &if_true, &if_false, &fall_through); 4137 &if_true, &if_false, &fall_through);
4121 4138
4122 VisitForAccumulatorValue(expr->expression()); 4139 VisitForAccumulatorValue(expr->expression());
4123 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); 4140 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
4124 4141
4125 __ cmp(eax, Factory::null_value()); 4142 __ cmp(eax, isolate()->factory()->null_value());
4126 if (expr->is_strict()) { 4143 if (expr->is_strict()) {
4127 Split(equal, if_true, if_false, fall_through); 4144 Split(equal, if_true, if_false, fall_through);
4128 } else { 4145 } else {
4129 __ j(equal, if_true); 4146 __ j(equal, if_true);
4130 __ cmp(eax, Factory::undefined_value()); 4147 __ cmp(eax, isolate()->factory()->undefined_value());
4131 __ j(equal, if_true); 4148 __ j(equal, if_true);
4132 __ test(eax, Immediate(kSmiTagMask)); 4149 __ test(eax, Immediate(kSmiTagMask));
4133 __ j(zero, if_false); 4150 __ j(zero, if_false);
4134 // It can be an undetectable object. 4151 // It can be an undetectable object.
4135 __ mov(edx, FieldOperand(eax, HeapObject::kMapOffset)); 4152 __ mov(edx, FieldOperand(eax, HeapObject::kMapOffset));
4136 __ movzx_b(edx, FieldOperand(edx, Map::kBitFieldOffset)); 4153 __ movzx_b(edx, FieldOperand(edx, Map::kBitFieldOffset));
4137 __ test(edx, Immediate(1 << Map::kIsUndetectable)); 4154 __ test(edx, Immediate(1 << Map::kIsUndetectable));
4138 Split(not_zero, if_true, if_false, fall_through); 4155 Split(not_zero, if_true, if_false, fall_through);
4139 } 4156 }
4140 context()->Plug(if_true, if_false); 4157 context()->Plug(if_true, if_false);
(...skipping 14 matching lines...) Expand all
4155 Register FullCodeGenerator::context_register() { 4172 Register FullCodeGenerator::context_register() {
4156 return esi; 4173 return esi;
4157 } 4174 }
4158 4175
4159 4176
4160 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, RelocInfo::Mode mode) { 4177 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, RelocInfo::Mode mode) {
4161 ASSERT(mode == RelocInfo::CODE_TARGET || 4178 ASSERT(mode == RelocInfo::CODE_TARGET ||
4162 mode == RelocInfo::CODE_TARGET_CONTEXT); 4179 mode == RelocInfo::CODE_TARGET_CONTEXT);
4163 switch (ic->kind()) { 4180 switch (ic->kind()) {
4164 case Code::LOAD_IC: 4181 case Code::LOAD_IC:
4165 __ IncrementCounter(&Counters::named_load_full, 1); 4182 __ IncrementCounter(isolate()->counters()->named_load_full(), 1);
4166 break; 4183 break;
4167 case Code::KEYED_LOAD_IC: 4184 case Code::KEYED_LOAD_IC:
4168 __ IncrementCounter(&Counters::keyed_load_full, 1); 4185 __ IncrementCounter(isolate()->counters()->keyed_load_full(), 1);
4169 break; 4186 break;
4170 case Code::STORE_IC: 4187 case Code::STORE_IC:
4171 __ IncrementCounter(&Counters::named_store_full, 1); 4188 __ IncrementCounter(isolate()->counters()->named_store_full(), 1);
4172 break; 4189 break;
4173 case Code::KEYED_STORE_IC: 4190 case Code::KEYED_STORE_IC:
4174 __ IncrementCounter(&Counters::keyed_store_full, 1); 4191 __ IncrementCounter(isolate()->counters()->keyed_store_full(), 1);
4175 default: 4192 default:
4176 break; 4193 break;
4177 } 4194 }
4178 4195
4179 __ call(ic, mode); 4196 __ call(ic, mode);
4180 4197
4181 // Crankshaft doesn't need patching of inlined loads and stores. 4198 // Crankshaft doesn't need patching of inlined loads and stores.
4182 // When compiling the snapshot we need to produce code that works 4199 // When compiling the snapshot we need to produce code that works
4183 // with and without Crankshaft. 4200 // with and without Crankshaft.
4184 if (V8::UseCrankshaft() && !Serializer::enabled()) { 4201 if (V8::UseCrankshaft() && !Serializer::enabled()) {
(...skipping 13 matching lines...) Expand all
4198 default: 4215 default:
4199 // Do nothing. 4216 // Do nothing.
4200 break; 4217 break;
4201 } 4218 }
4202 } 4219 }
4203 4220
4204 4221
4205 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, JumpPatchSite* patch_site) { 4222 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, JumpPatchSite* patch_site) {
4206 switch (ic->kind()) { 4223 switch (ic->kind()) {
4207 case Code::LOAD_IC: 4224 case Code::LOAD_IC:
4208 __ IncrementCounter(&Counters::named_load_full, 1); 4225 __ IncrementCounter(COUNTERS->named_load_full(), 1);
4209 break; 4226 break;
4210 case Code::KEYED_LOAD_IC: 4227 case Code::KEYED_LOAD_IC:
4211 __ IncrementCounter(&Counters::keyed_load_full, 1); 4228 __ IncrementCounter(COUNTERS->keyed_load_full(), 1);
4212 break; 4229 break;
4213 case Code::STORE_IC: 4230 case Code::STORE_IC:
4214 __ IncrementCounter(&Counters::named_store_full, 1); 4231 __ IncrementCounter(COUNTERS->named_store_full(), 1);
4215 break; 4232 break;
4216 case Code::KEYED_STORE_IC: 4233 case Code::KEYED_STORE_IC:
4217 __ IncrementCounter(&Counters::keyed_store_full, 1); 4234 __ IncrementCounter(COUNTERS->keyed_store_full(), 1);
4218 default: 4235 default:
4219 break; 4236 break;
4220 } 4237 }
4221 4238
4222 __ call(ic, RelocInfo::CODE_TARGET); 4239 __ call(ic, RelocInfo::CODE_TARGET);
4223 if (patch_site != NULL && patch_site->is_bound()) { 4240 if (patch_site != NULL && patch_site->is_bound()) {
4224 patch_site->EmitPatchInfo(); 4241 patch_site->EmitPatchInfo();
4225 } else { 4242 } else {
4226 __ nop(); // Signals no inlined code. 4243 __ nop(); // Signals no inlined code.
4227 } 4244 }
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
4268 // And return. 4285 // And return.
4269 __ ret(0); 4286 __ ret(0);
4270 } 4287 }
4271 4288
4272 4289
4273 #undef __ 4290 #undef __
4274 4291
4275 } } // namespace v8::internal 4292 } } // namespace v8::internal
4276 4293
4277 #endif // V8_TARGET_ARCH_IA32 4294 #endif // V8_TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698