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

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

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

Powered by Google App Engine
This is Rietveld 408576698