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

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

Issue 6542061: [Isolates] Less TLS reads in parser and full codegens. (Closed)
Patch Set: Created 9 years, 10 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
« no previous file with comments | « src/full-codegen.cc ('k') | src/parser.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 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 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
70 #endif 70 #endif
71 71
72 __ push(ebp); // Caller's frame pointer. 72 __ push(ebp); // Caller's frame pointer.
73 __ mov(ebp, esp); 73 __ mov(ebp, esp);
74 __ push(esi); // Callee's context. 74 __ push(esi); // Callee's context.
75 __ push(edi); // Callee's JS Function. 75 __ push(edi); // Callee's JS Function.
76 76
77 { Comment cmnt(masm_, "[ Allocate locals"); 77 { Comment cmnt(masm_, "[ Allocate locals");
78 int locals_count = scope()->num_stack_slots(); 78 int locals_count = scope()->num_stack_slots();
79 if (locals_count == 1) { 79 if (locals_count == 1) {
80 __ push(Immediate(FACTORY->undefined_value())); 80 __ push(Immediate(isolate()->factory()->undefined_value()));
81 } else if (locals_count > 1) { 81 } else if (locals_count > 1) {
82 __ mov(eax, Immediate(FACTORY->undefined_value())); 82 __ mov(eax, Immediate(isolate()->factory()->undefined_value()));
83 for (int i = 0; i < locals_count; i++) { 83 for (int i = 0; i < locals_count; i++) {
84 __ push(eax); 84 __ push(eax);
85 } 85 }
86 } 86 }
87 } 87 }
88 88
89 bool function_in_register = true; 89 bool function_in_register = true;
90 90
91 // Possibly allocate a local context. 91 // Possibly allocate a local context.
92 int heap_slots = scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; 92 int heap_slots = scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
185 } 185 }
186 186
187 { Comment cmnt(masm_, "[ Body"); 187 { Comment cmnt(masm_, "[ Body");
188 ASSERT(loop_depth() == 0); 188 ASSERT(loop_depth() == 0);
189 VisitStatements(function()->body()); 189 VisitStatements(function()->body());
190 ASSERT(loop_depth() == 0); 190 ASSERT(loop_depth() == 0);
191 } 191 }
192 192
193 { Comment cmnt(masm_, "[ return <undefined>;"); 193 { Comment cmnt(masm_, "[ return <undefined>;");
194 // Emit a 'return undefined' in case control fell off the end of the body. 194 // Emit a 'return undefined' in case control fell off the end of the body.
195 __ mov(eax, FACTORY->undefined_value()); 195 __ mov(eax, isolate()->factory()->undefined_value());
196 EmitReturnSequence(); 196 EmitReturnSequence();
197 } 197 }
198 } 198 }
199 199
200 200
201 void FullCodeGenerator::EmitStackCheck(IterationStatement* stmt) { 201 void FullCodeGenerator::EmitStackCheck(IterationStatement* stmt) {
202 Comment cmnt(masm_, "[ Stack check"); 202 Comment cmnt(masm_, "[ Stack check");
203 NearLabel ok; 203 NearLabel ok;
204 ExternalReference stack_limit = ExternalReference::address_of_stack_limit(); 204 ExternalReference stack_limit = ExternalReference::address_of_stack_limit();
205 __ cmp(esp, Operand::StaticVariable(stack_limit)); 205 __ cmp(esp, Operand::StaticVariable(stack_limit));
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
401 ASSERT(materialize_true == materialize_false); 401 ASSERT(materialize_true == materialize_false);
402 __ bind(materialize_true); 402 __ bind(materialize_true);
403 } 403 }
404 404
405 405
406 void FullCodeGenerator::AccumulatorValueContext::Plug( 406 void FullCodeGenerator::AccumulatorValueContext::Plug(
407 Label* materialize_true, 407 Label* materialize_true,
408 Label* materialize_false) const { 408 Label* materialize_false) const {
409 NearLabel done; 409 NearLabel done;
410 __ bind(materialize_true); 410 __ bind(materialize_true);
411 __ mov(result_register(), FACTORY->true_value()); 411 __ mov(result_register(), isolate()->factory()->true_value());
412 __ jmp(&done); 412 __ jmp(&done);
413 __ bind(materialize_false); 413 __ bind(materialize_false);
414 __ mov(result_register(), FACTORY->false_value()); 414 __ mov(result_register(), isolate()->factory()->false_value());
415 __ bind(&done); 415 __ bind(&done);
416 } 416 }
417 417
418 418
419 void FullCodeGenerator::StackValueContext::Plug( 419 void FullCodeGenerator::StackValueContext::Plug(
420 Label* materialize_true, 420 Label* materialize_true,
421 Label* materialize_false) const { 421 Label* materialize_false) const {
422 NearLabel done; 422 NearLabel done;
423 __ bind(materialize_true); 423 __ bind(materialize_true);
424 __ push(Immediate(FACTORY->true_value())); 424 __ push(Immediate(isolate()->factory()->true_value()));
425 __ jmp(&done); 425 __ jmp(&done);
426 __ bind(materialize_false); 426 __ bind(materialize_false);
427 __ push(Immediate(FACTORY->false_value())); 427 __ push(Immediate(isolate()->factory()->false_value()));
428 __ bind(&done); 428 __ bind(&done);
429 } 429 }
430 430
431 431
432 void FullCodeGenerator::TestContext::Plug(Label* materialize_true, 432 void FullCodeGenerator::TestContext::Plug(Label* materialize_true,
433 Label* materialize_false) const { 433 Label* materialize_false) const {
434 ASSERT(materialize_true == true_label_); 434 ASSERT(materialize_true == true_label_);
435 ASSERT(materialize_false == false_label_); 435 ASSERT(materialize_false == false_label_);
436 } 436 }
437 437
438 438
439 void FullCodeGenerator::EffectContext::Plug(bool flag) const { 439 void FullCodeGenerator::EffectContext::Plug(bool flag) const {
440 } 440 }
441 441
442 442
443 void FullCodeGenerator::AccumulatorValueContext::Plug(bool flag) const { 443 void FullCodeGenerator::AccumulatorValueContext::Plug(bool flag) const {
444 Handle<Object> value = 444 Handle<Object> value = flag
445 flag ? FACTORY->true_value() : FACTORY->false_value(); 445 ? isolate()->factory()->true_value()
446 : isolate()->factory()->false_value();
446 __ mov(result_register(), value); 447 __ mov(result_register(), value);
447 } 448 }
448 449
449 450
450 void FullCodeGenerator::StackValueContext::Plug(bool flag) const { 451 void FullCodeGenerator::StackValueContext::Plug(bool flag) const {
451 Handle<Object> value = 452 Handle<Object> value = flag
452 flag ? FACTORY->true_value() : FACTORY->false_value(); 453 ? isolate()->factory()->true_value()
454 : isolate()->factory()->false_value();
453 __ push(Immediate(value)); 455 __ push(Immediate(value));
454 } 456 }
455 457
456 458
457 void FullCodeGenerator::TestContext::Plug(bool flag) const { 459 void FullCodeGenerator::TestContext::Plug(bool flag) const {
458 codegen()->PrepareForBailoutBeforeSplit(TOS_REG, 460 codegen()->PrepareForBailoutBeforeSplit(TOS_REG,
459 true, 461 true,
460 true_label_, 462 true_label_,
461 false_label_); 463 false_label_);
462 if (flag) { 464 if (flag) {
463 if (true_label_ != fall_through_) __ jmp(true_label_); 465 if (true_label_ != fall_through_) __ jmp(true_label_);
464 } else { 466 } else {
465 if (false_label_ != fall_through_) __ jmp(false_label_); 467 if (false_label_ != fall_through_) __ jmp(false_label_);
466 } 468 }
467 } 469 }
468 470
469 471
470 void FullCodeGenerator::DoTest(Label* if_true, 472 void FullCodeGenerator::DoTest(Label* if_true,
471 Label* if_false, 473 Label* if_false,
472 Label* fall_through) { 474 Label* fall_through) {
473 // Emit the inlined tests assumed by the stub. 475 // Emit the inlined tests assumed by the stub.
474 __ cmp(result_register(), FACTORY->undefined_value()); 476 __ cmp(result_register(), isolate()->factory()->undefined_value());
475 __ j(equal, if_false); 477 __ j(equal, if_false);
476 __ cmp(result_register(), FACTORY->true_value()); 478 __ cmp(result_register(), isolate()->factory()->true_value());
477 __ j(equal, if_true); 479 __ j(equal, if_true);
478 __ cmp(result_register(), FACTORY->false_value()); 480 __ cmp(result_register(), isolate()->factory()->false_value());
479 __ j(equal, if_false); 481 __ j(equal, if_false);
480 ASSERT_EQ(0, kSmiTag); 482 ASSERT_EQ(0, kSmiTag);
481 __ test(result_register(), Operand(result_register())); 483 __ test(result_register(), Operand(result_register()));
482 __ j(zero, if_false); 484 __ j(zero, if_false);
483 __ test(result_register(), Immediate(kSmiTagMask)); 485 __ test(result_register(), Immediate(kSmiTagMask));
484 __ j(zero, if_true); 486 __ j(zero, if_true);
485 487
486 // Call the ToBoolean stub for all other cases. 488 // Call the ToBoolean stub for all other cases.
487 ToBooleanStub stub; 489 ToBooleanStub stub;
488 __ push(result_register()); 490 __ push(result_register());
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
562 NearLabel skip; 564 NearLabel skip;
563 if (should_normalize) __ jmp(&skip); 565 if (should_normalize) __ jmp(&skip);
564 566
565 ForwardBailoutStack* current = forward_bailout_stack_; 567 ForwardBailoutStack* current = forward_bailout_stack_;
566 while (current != NULL) { 568 while (current != NULL) {
567 PrepareForBailout(current->expr(), state); 569 PrepareForBailout(current->expr(), state);
568 current = current->parent(); 570 current = current->parent();
569 } 571 }
570 572
571 if (should_normalize) { 573 if (should_normalize) {
572 __ cmp(eax, FACTORY->true_value()); 574 __ cmp(eax, isolate()->factory()->true_value());
573 Split(equal, if_true, if_false, NULL); 575 Split(equal, if_true, if_false, NULL);
574 __ bind(&skip); 576 __ bind(&skip);
575 } 577 }
576 } 578 }
577 579
578 580
579 void FullCodeGenerator::EmitDeclaration(Variable* variable, 581 void FullCodeGenerator::EmitDeclaration(Variable* variable,
580 Variable::Mode mode, 582 Variable::Mode mode,
581 FunctionLiteral* function) { 583 FunctionLiteral* function) {
582 Comment cmnt(masm_, "[ Declaration"); 584 Comment cmnt(masm_, "[ Declaration");
583 ASSERT(variable != NULL); // Must have been resolved. 585 ASSERT(variable != NULL); // Must have been resolved.
584 Slot* slot = variable->AsSlot(); 586 Slot* slot = variable->AsSlot();
585 Property* prop = variable->AsProperty(); 587 Property* prop = variable->AsProperty();
586 if (slot != NULL) { 588 if (slot != NULL) {
587 switch (slot->type()) { 589 switch (slot->type()) {
588 case Slot::PARAMETER: 590 case Slot::PARAMETER:
589 case Slot::LOCAL: 591 case Slot::LOCAL:
590 if (mode == Variable::CONST) { 592 if (mode == Variable::CONST) {
591 __ mov(Operand(ebp, SlotOffset(slot)), 593 __ mov(Operand(ebp, SlotOffset(slot)),
592 Immediate(FACTORY->the_hole_value())); 594 Immediate(isolate()->factory()->the_hole_value()));
593 } else if (function != NULL) { 595 } else if (function != NULL) {
594 VisitForAccumulatorValue(function); 596 VisitForAccumulatorValue(function);
595 __ mov(Operand(ebp, SlotOffset(slot)), result_register()); 597 __ mov(Operand(ebp, SlotOffset(slot)), result_register());
596 } 598 }
597 break; 599 break;
598 600
599 case Slot::CONTEXT: 601 case Slot::CONTEXT:
600 // We bypass the general EmitSlotSearch because we know more about 602 // We bypass the general EmitSlotSearch because we know more about
601 // this specific context. 603 // this specific context.
602 604
603 // The variable in the decl always resides in the current context. 605 // The variable in the decl always resides in the current context.
604 ASSERT_EQ(0, scope()->ContextChainLength(variable->scope())); 606 ASSERT_EQ(0, scope()->ContextChainLength(variable->scope()));
605 if (FLAG_debug_code) { 607 if (FLAG_debug_code) {
606 // Check if we have the correct context pointer. 608 // Check if we have the correct context pointer.
607 __ mov(ebx, ContextOperand(esi, Context::FCONTEXT_INDEX)); 609 __ mov(ebx, ContextOperand(esi, Context::FCONTEXT_INDEX));
608 __ cmp(ebx, Operand(esi)); 610 __ cmp(ebx, Operand(esi));
609 __ Check(equal, "Unexpected declaration in current context."); 611 __ Check(equal, "Unexpected declaration in current context.");
610 } 612 }
611 if (mode == Variable::CONST) { 613 if (mode == Variable::CONST) {
612 __ mov(ContextOperand(esi, slot->index()), 614 __ mov(ContextOperand(esi, slot->index()),
613 Immediate(FACTORY->the_hole_value())); 615 Immediate(isolate()->factory()->the_hole_value()));
614 // No write barrier since the hole value is in old space. 616 // No write barrier since the hole value is in old space.
615 } else if (function != NULL) { 617 } else if (function != NULL) {
616 VisitForAccumulatorValue(function); 618 VisitForAccumulatorValue(function);
617 __ mov(ContextOperand(esi, slot->index()), result_register()); 619 __ mov(ContextOperand(esi, slot->index()), result_register());
618 int offset = Context::SlotOffset(slot->index()); 620 int offset = Context::SlotOffset(slot->index());
619 __ mov(ebx, esi); 621 __ mov(ebx, esi);
620 __ RecordWrite(ebx, offset, result_register(), ecx); 622 __ RecordWrite(ebx, offset, result_register(), ecx);
621 } 623 }
622 break; 624 break;
623 625
624 case Slot::LOOKUP: { 626 case Slot::LOOKUP: {
625 __ push(esi); 627 __ push(esi);
626 __ push(Immediate(variable->name())); 628 __ push(Immediate(variable->name()));
627 // Declaration nodes are always introduced in one of two modes. 629 // Declaration nodes are always introduced in one of two modes.
628 ASSERT(mode == Variable::VAR || mode == Variable::CONST); 630 ASSERT(mode == Variable::VAR || mode == Variable::CONST);
629 PropertyAttributes attr = (mode == Variable::VAR) ? NONE : READ_ONLY; 631 PropertyAttributes attr = (mode == Variable::VAR) ? NONE : READ_ONLY;
630 __ push(Immediate(Smi::FromInt(attr))); 632 __ push(Immediate(Smi::FromInt(attr)));
631 // Push initial value, if any. 633 // Push initial value, if any.
632 // Note: For variables we must not push an initial value (such as 634 // Note: For variables we must not push an initial value (such as
633 // 'undefined') because we may have a (legal) redeclaration and we 635 // 'undefined') because we may have a (legal) redeclaration and we
634 // must not destroy the current value. 636 // must not destroy the current value.
635 if (mode == Variable::CONST) { 637 if (mode == Variable::CONST) {
636 __ push(Immediate(FACTORY->the_hole_value())); 638 __ push(Immediate(isolate()->factory()->the_hole_value()));
637 } else if (function != NULL) { 639 } else if (function != NULL) {
638 VisitForStackValue(function); 640 VisitForStackValue(function);
639 } else { 641 } else {
640 __ push(Immediate(Smi::FromInt(0))); // No initial value! 642 __ push(Immediate(Smi::FromInt(0))); // No initial value!
641 } 643 }
642 __ CallRuntime(Runtime::kDeclareContextSlot, 4); 644 __ CallRuntime(Runtime::kDeclareContextSlot, 4);
643 break; 645 break;
644 } 646 }
645 } 647 }
646 648
647 } else if (prop != NULL) { 649 } else if (prop != NULL) {
648 if (function != NULL || mode == Variable::CONST) { 650 if (function != NULL || mode == Variable::CONST) {
649 // We are declaring a function or constant that rewrites to a 651 // We are declaring a function or constant that rewrites to a
650 // property. Use (keyed) IC to set the initial value. 652 // property. Use (keyed) IC to set the initial value.
651 VisitForStackValue(prop->obj()); 653 VisitForStackValue(prop->obj());
652 if (function != NULL) { 654 if (function != NULL) {
653 VisitForStackValue(prop->key()); 655 VisitForStackValue(prop->key());
654 VisitForAccumulatorValue(function); 656 VisitForAccumulatorValue(function);
655 __ pop(ecx); 657 __ pop(ecx);
656 } else { 658 } else {
657 VisitForAccumulatorValue(prop->key()); 659 VisitForAccumulatorValue(prop->key());
658 __ mov(ecx, result_register()); 660 __ mov(ecx, result_register());
659 __ mov(result_register(), FACTORY->the_hole_value()); 661 __ mov(result_register(), isolate()->factory()->the_hole_value());
660 } 662 }
661 __ pop(edx); 663 __ pop(edx);
662 664
663 Handle<Code> ic(Isolate::Current()->builtins()->builtin( 665 Handle<Code> ic(isolate()->builtins()->builtin(
664 Builtins::KeyedStoreIC_Initialize)); 666 Builtins::KeyedStoreIC_Initialize));
665 EmitCallIC(ic, RelocInfo::CODE_TARGET); 667 EmitCallIC(ic, RelocInfo::CODE_TARGET);
666 } 668 }
667 } 669 }
668 } 670 }
669 671
670 672
671 void FullCodeGenerator::VisitDeclaration(Declaration* decl) { 673 void FullCodeGenerator::VisitDeclaration(Declaration* decl) {
672 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun()); 674 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun());
673 } 675 }
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
769 SetStatementPosition(stmt); 771 SetStatementPosition(stmt);
770 772
771 Label loop, exit; 773 Label loop, exit;
772 ForIn loop_statement(this, stmt); 774 ForIn loop_statement(this, stmt);
773 increment_loop_depth(); 775 increment_loop_depth();
774 776
775 // Get the object to enumerate over. Both SpiderMonkey and JSC 777 // Get the object to enumerate over. Both SpiderMonkey and JSC
776 // ignore null and undefined in contrast to the specification; see 778 // ignore null and undefined in contrast to the specification; see
777 // ECMA-262 section 12.6.4. 779 // ECMA-262 section 12.6.4.
778 VisitForAccumulatorValue(stmt->enumerable()); 780 VisitForAccumulatorValue(stmt->enumerable());
779 __ cmp(eax, FACTORY->undefined_value()); 781 __ cmp(eax, isolate()->factory()->undefined_value());
780 __ j(equal, &exit); 782 __ j(equal, &exit);
781 __ cmp(eax, FACTORY->null_value()); 783 __ cmp(eax, isolate()->factory()->null_value());
782 __ j(equal, &exit); 784 __ j(equal, &exit);
783 785
784 // Convert the object to a JS object. 786 // Convert the object to a JS object.
785 NearLabel convert, done_convert; 787 NearLabel convert, done_convert;
786 __ test(eax, Immediate(kSmiTagMask)); 788 __ test(eax, Immediate(kSmiTagMask));
787 __ j(zero, &convert); 789 __ j(zero, &convert);
788 __ CmpObjectType(eax, FIRST_JS_OBJECT_TYPE, ecx); 790 __ CmpObjectType(eax, FIRST_JS_OBJECT_TYPE, ecx);
789 __ j(above_equal, &done_convert); 791 __ j(above_equal, &done_convert);
790 __ bind(&convert); 792 __ bind(&convert);
791 __ push(eax); 793 __ push(eax);
792 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION); 794 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
793 __ bind(&done_convert); 795 __ bind(&done_convert);
794 __ push(eax); 796 __ push(eax);
795 797
796 // Check cache validity in generated code. This is a fast case for 798 // Check cache validity in generated code. This is a fast case for
797 // the JSObject::IsSimpleEnum cache validity checks. If we cannot 799 // the JSObject::IsSimpleEnum cache validity checks. If we cannot
798 // guarantee cache validity, call the runtime system to check cache 800 // guarantee cache validity, call the runtime system to check cache
799 // validity or get the property names in a fixed array. 801 // validity or get the property names in a fixed array.
800 Label next, call_runtime; 802 Label next, call_runtime;
801 __ mov(ecx, eax); 803 __ mov(ecx, eax);
802 __ bind(&next); 804 __ bind(&next);
803 805
804 // Check that there are no elements. Register ecx contains the 806 // Check that there are no elements. Register ecx contains the
805 // current JS object we've reached through the prototype chain. 807 // current JS object we've reached through the prototype chain.
806 __ cmp(FieldOperand(ecx, JSObject::kElementsOffset), 808 __ cmp(FieldOperand(ecx, JSObject::kElementsOffset),
807 FACTORY->empty_fixed_array()); 809 isolate()->factory()->empty_fixed_array());
808 __ j(not_equal, &call_runtime); 810 __ j(not_equal, &call_runtime);
809 811
810 // Check that instance descriptors are not empty so that we can 812 // Check that instance descriptors are not empty so that we can
811 // check for an enum cache. Leave the map in ebx for the subsequent 813 // check for an enum cache. Leave the map in ebx for the subsequent
812 // prototype load. 814 // prototype load.
813 __ mov(ebx, FieldOperand(ecx, HeapObject::kMapOffset)); 815 __ mov(ebx, FieldOperand(ecx, HeapObject::kMapOffset));
814 __ mov(edx, FieldOperand(ebx, Map::kInstanceDescriptorsOffset)); 816 __ mov(edx, FieldOperand(ebx, Map::kInstanceDescriptorsOffset));
815 __ cmp(edx, FACTORY->empty_descriptor_array()); 817 __ cmp(edx, isolate()->factory()->empty_descriptor_array());
816 __ j(equal, &call_runtime); 818 __ j(equal, &call_runtime);
817 819
818 // Check that there in an enum cache in the non-empty instance 820 // Check that there in an enum cache in the non-empty instance
819 // descriptors (edx). This is the case if the next enumeration 821 // descriptors (edx). This is the case if the next enumeration
820 // index field does not contain a smi. 822 // index field does not contain a smi.
821 __ mov(edx, FieldOperand(edx, DescriptorArray::kEnumerationIndexOffset)); 823 __ mov(edx, FieldOperand(edx, DescriptorArray::kEnumerationIndexOffset));
822 __ test(edx, Immediate(kSmiTagMask)); 824 __ test(edx, Immediate(kSmiTagMask));
823 __ j(zero, &call_runtime); 825 __ j(zero, &call_runtime);
824 826
825 // For all objects but the receiver, check that the cache is empty. 827 // For all objects but the receiver, check that the cache is empty.
826 NearLabel check_prototype; 828 NearLabel check_prototype;
827 __ cmp(ecx, Operand(eax)); 829 __ cmp(ecx, Operand(eax));
828 __ j(equal, &check_prototype); 830 __ j(equal, &check_prototype);
829 __ mov(edx, FieldOperand(edx, DescriptorArray::kEnumCacheBridgeCacheOffset)); 831 __ mov(edx, FieldOperand(edx, DescriptorArray::kEnumCacheBridgeCacheOffset));
830 __ cmp(edx, FACTORY->empty_fixed_array()); 832 __ cmp(edx, isolate()->factory()->empty_fixed_array());
831 __ j(not_equal, &call_runtime); 833 __ j(not_equal, &call_runtime);
832 834
833 // Load the prototype from the map and loop if non-null. 835 // Load the prototype from the map and loop if non-null.
834 __ bind(&check_prototype); 836 __ bind(&check_prototype);
835 __ mov(ecx, FieldOperand(ebx, Map::kPrototypeOffset)); 837 __ mov(ecx, FieldOperand(ebx, Map::kPrototypeOffset));
836 __ cmp(ecx, FACTORY->null_value()); 838 __ cmp(ecx, isolate()->factory()->null_value());
837 __ j(not_equal, &next); 839 __ j(not_equal, &next);
838 840
839 // The enum cache is valid. Load the map of the object being 841 // The enum cache is valid. Load the map of the object being
840 // iterated over and use the cache for the iteration. 842 // iterated over and use the cache for the iteration.
841 NearLabel use_cache; 843 NearLabel use_cache;
842 __ mov(eax, FieldOperand(eax, HeapObject::kMapOffset)); 844 __ mov(eax, FieldOperand(eax, HeapObject::kMapOffset));
843 __ jmp(&use_cache); 845 __ jmp(&use_cache);
844 846
845 // Get the set of properties to enumerate. 847 // Get the set of properties to enumerate.
846 __ bind(&call_runtime); 848 __ bind(&call_runtime);
847 __ push(eax); // Duplicate the enumerable object on the stack. 849 __ push(eax); // Duplicate the enumerable object on the stack.
848 __ CallRuntime(Runtime::kGetPropertyNamesFast, 1); 850 __ CallRuntime(Runtime::kGetPropertyNamesFast, 1);
849 851
850 // If we got a map from the runtime call, we can do a fast 852 // If we got a map from the runtime call, we can do a fast
851 // modification check. Otherwise, we got a fixed array, and we have 853 // modification check. Otherwise, we got a fixed array, and we have
852 // to do a slow check. 854 // to do a slow check.
853 NearLabel fixed_array; 855 NearLabel fixed_array;
854 __ cmp(FieldOperand(eax, HeapObject::kMapOffset), FACTORY->meta_map()); 856 __ cmp(FieldOperand(eax, HeapObject::kMapOffset),
857 isolate()->factory()->meta_map());
855 __ j(not_equal, &fixed_array); 858 __ j(not_equal, &fixed_array);
856 859
857 // We got a map in register eax. Get the enumeration cache from it. 860 // We got a map in register eax. Get the enumeration cache from it.
858 __ bind(&use_cache); 861 __ bind(&use_cache);
859 __ mov(ecx, FieldOperand(eax, Map::kInstanceDescriptorsOffset)); 862 __ mov(ecx, FieldOperand(eax, Map::kInstanceDescriptorsOffset));
860 __ mov(ecx, FieldOperand(ecx, DescriptorArray::kEnumerationIndexOffset)); 863 __ mov(ecx, FieldOperand(ecx, DescriptorArray::kEnumerationIndexOffset));
861 __ mov(edx, FieldOperand(ecx, DescriptorArray::kEnumCacheBridgeCacheOffset)); 864 __ mov(edx, FieldOperand(ecx, DescriptorArray::kEnumCacheBridgeCacheOffset));
862 865
863 // Setup the four remaining stack slots. 866 // Setup the four remaining stack slots.
864 __ push(eax); // Map. 867 __ push(eax); // Map.
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
948 scope()->is_function_scope() && 951 scope()->is_function_scope() &&
949 info->num_literals() == 0 && 952 info->num_literals() == 0 &&
950 !pretenure) { 953 !pretenure) {
951 FastNewClosureStub stub; 954 FastNewClosureStub stub;
952 __ push(Immediate(info)); 955 __ push(Immediate(info));
953 __ CallStub(&stub); 956 __ CallStub(&stub);
954 } else { 957 } else {
955 __ push(esi); 958 __ push(esi);
956 __ push(Immediate(info)); 959 __ push(Immediate(info));
957 __ push(Immediate(pretenure 960 __ push(Immediate(pretenure
958 ? FACTORY->true_value() 961 ? isolate()->factory()->true_value()
959 : FACTORY->false_value())); 962 : isolate()->factory()->false_value()));
960 __ CallRuntime(Runtime::kNewClosure, 3); 963 __ CallRuntime(Runtime::kNewClosure, 3);
961 } 964 }
962 context()->Plug(eax); 965 context()->Plug(eax);
963 } 966 }
964 967
965 968
966 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) { 969 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
967 Comment cmnt(masm_, "[ VariableProxy"); 970 Comment cmnt(masm_, "[ VariableProxy");
968 EmitVariableLoad(expr->var()); 971 EmitVariableLoad(expr->var());
969 } 972 }
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1001 if (s != NULL && s->is_eval_scope()) { 1004 if (s != NULL && s->is_eval_scope()) {
1002 // Loop up the context chain. There is no frame effect so it is 1005 // Loop up the context chain. There is no frame effect so it is
1003 // safe to use raw labels here. 1006 // safe to use raw labels here.
1004 NearLabel next, fast; 1007 NearLabel next, fast;
1005 if (!context.is(temp)) { 1008 if (!context.is(temp)) {
1006 __ mov(temp, context); 1009 __ mov(temp, context);
1007 } 1010 }
1008 __ bind(&next); 1011 __ bind(&next);
1009 // Terminate at global context. 1012 // Terminate at global context.
1010 __ cmp(FieldOperand(temp, HeapObject::kMapOffset), 1013 __ cmp(FieldOperand(temp, HeapObject::kMapOffset),
1011 Immediate(FACTORY->global_context_map())); 1014 Immediate(isolate()->factory()->global_context_map()));
1012 __ j(equal, &fast); 1015 __ j(equal, &fast);
1013 // Check that extension is NULL. 1016 // Check that extension is NULL.
1014 __ cmp(ContextOperand(temp, Context::EXTENSION_INDEX), Immediate(0)); 1017 __ cmp(ContextOperand(temp, Context::EXTENSION_INDEX), Immediate(0));
1015 __ j(not_equal, slow); 1018 __ j(not_equal, slow);
1016 // Load next context in chain. 1019 // Load next context in chain.
1017 __ mov(temp, ContextOperand(temp, Context::CLOSURE_INDEX)); 1020 __ mov(temp, ContextOperand(temp, Context::CLOSURE_INDEX));
1018 __ mov(temp, FieldOperand(temp, JSFunction::kContextOffset)); 1021 __ mov(temp, FieldOperand(temp, JSFunction::kContextOffset));
1019 __ jmp(&next); 1022 __ jmp(&next);
1020 __ bind(&fast); 1023 __ bind(&fast);
1021 } 1024 }
1022 1025
1023 // All extension objects were empty and it is safe to use a global 1026 // All extension objects were empty and it is safe to use a global
1024 // load IC call. 1027 // load IC call.
1025 __ mov(eax, GlobalObjectOperand()); 1028 __ mov(eax, GlobalObjectOperand());
1026 __ mov(ecx, slot->var()->name()); 1029 __ mov(ecx, slot->var()->name());
1027 Handle<Code> ic(Isolate::Current()->builtins()->builtin( 1030 Handle<Code> ic(isolate()->builtins()->builtin(
1028 Builtins::LoadIC_Initialize)); 1031 Builtins::LoadIC_Initialize));
1029 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF) 1032 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF)
1030 ? RelocInfo::CODE_TARGET 1033 ? RelocInfo::CODE_TARGET
1031 : RelocInfo::CODE_TARGET_CONTEXT; 1034 : RelocInfo::CODE_TARGET_CONTEXT;
1032 EmitCallIC(ic, mode); 1035 EmitCallIC(ic, mode);
1033 } 1036 }
1034 1037
1035 1038
1036 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions( 1039 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(
1037 Slot* slot, 1040 Slot* slot,
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1076 EmitLoadGlobalSlotCheckExtensions(slot, typeof_state, slow); 1079 EmitLoadGlobalSlotCheckExtensions(slot, typeof_state, slow);
1077 __ jmp(done); 1080 __ jmp(done);
1078 } else if (slot->var()->mode() == Variable::DYNAMIC_LOCAL) { 1081 } else if (slot->var()->mode() == Variable::DYNAMIC_LOCAL) {
1079 Slot* potential_slot = slot->var()->local_if_not_shadowed()->AsSlot(); 1082 Slot* potential_slot = slot->var()->local_if_not_shadowed()->AsSlot();
1080 Expression* rewrite = slot->var()->local_if_not_shadowed()->rewrite(); 1083 Expression* rewrite = slot->var()->local_if_not_shadowed()->rewrite();
1081 if (potential_slot != NULL) { 1084 if (potential_slot != NULL) {
1082 // Generate fast case for locals that rewrite to slots. 1085 // Generate fast case for locals that rewrite to slots.
1083 __ mov(eax, 1086 __ mov(eax,
1084 ContextSlotOperandCheckExtensions(potential_slot, slow)); 1087 ContextSlotOperandCheckExtensions(potential_slot, slow));
1085 if (potential_slot->var()->mode() == Variable::CONST) { 1088 if (potential_slot->var()->mode() == Variable::CONST) {
1086 __ cmp(eax, FACTORY->the_hole_value()); 1089 __ cmp(eax, isolate()->factory()->the_hole_value());
1087 __ j(not_equal, done); 1090 __ j(not_equal, done);
1088 __ mov(eax, FACTORY->undefined_value()); 1091 __ mov(eax, isolate()->factory()->undefined_value());
1089 } 1092 }
1090 __ jmp(done); 1093 __ jmp(done);
1091 } else if (rewrite != NULL) { 1094 } else if (rewrite != NULL) {
1092 // Generate fast case for calls of an argument function. 1095 // Generate fast case for calls of an argument function.
1093 Property* property = rewrite->AsProperty(); 1096 Property* property = rewrite->AsProperty();
1094 if (property != NULL) { 1097 if (property != NULL) {
1095 VariableProxy* obj_proxy = property->obj()->AsVariableProxy(); 1098 VariableProxy* obj_proxy = property->obj()->AsVariableProxy();
1096 Literal* key_literal = property->key()->AsLiteral(); 1099 Literal* key_literal = property->key()->AsLiteral();
1097 if (obj_proxy != NULL && 1100 if (obj_proxy != NULL &&
1098 key_literal != NULL && 1101 key_literal != NULL &&
1099 obj_proxy->IsArguments() && 1102 obj_proxy->IsArguments() &&
1100 key_literal->handle()->IsSmi()) { 1103 key_literal->handle()->IsSmi()) {
1101 // Load arguments object if there are no eval-introduced 1104 // Load arguments object if there are no eval-introduced
1102 // variables. Then load the argument from the arguments 1105 // variables. Then load the argument from the arguments
1103 // object using keyed load. 1106 // object using keyed load.
1104 __ mov(edx, 1107 __ mov(edx,
1105 ContextSlotOperandCheckExtensions(obj_proxy->var()->AsSlot(), 1108 ContextSlotOperandCheckExtensions(obj_proxy->var()->AsSlot(),
1106 slow)); 1109 slow));
1107 __ mov(eax, Immediate(key_literal->handle())); 1110 __ mov(eax, Immediate(key_literal->handle()));
1108 Handle<Code> ic(Isolate::Current()->builtins()->builtin( 1111 Handle<Code> ic(isolate()->builtins()->builtin(
1109 Builtins::KeyedLoadIC_Initialize)); 1112 Builtins::KeyedLoadIC_Initialize));
1110 EmitCallIC(ic, RelocInfo::CODE_TARGET); 1113 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1111 __ jmp(done); 1114 __ jmp(done);
1112 } 1115 }
1113 } 1116 }
1114 } 1117 }
1115 } 1118 }
1116 } 1119 }
1117 1120
1118 1121
1119 void FullCodeGenerator::EmitVariableLoad(Variable* var) { 1122 void FullCodeGenerator::EmitVariableLoad(Variable* var) {
1120 // Four cases: non-this global variables, lookup slots, all other 1123 // Four cases: non-this global variables, lookup slots, all other
1121 // types of slots, and parameters that rewrite to explicit property 1124 // types of slots, and parameters that rewrite to explicit property
1122 // accesses on the arguments object. 1125 // accesses on the arguments object.
1123 Slot* slot = var->AsSlot(); 1126 Slot* slot = var->AsSlot();
1124 Property* property = var->AsProperty(); 1127 Property* property = var->AsProperty();
1125 1128
1126 if (var->is_global() && !var->is_this()) { 1129 if (var->is_global() && !var->is_this()) {
1127 Comment cmnt(masm_, "Global variable"); 1130 Comment cmnt(masm_, "Global variable");
1128 // Use inline caching. Variable name is passed in ecx and the global 1131 // Use inline caching. Variable name is passed in ecx and the global
1129 // object on the stack. 1132 // object on the stack.
1130 __ mov(eax, GlobalObjectOperand()); 1133 __ mov(eax, GlobalObjectOperand());
1131 __ mov(ecx, var->name()); 1134 __ mov(ecx, var->name());
1132 Handle<Code> ic(Isolate::Current()->builtins()->builtin( 1135 Handle<Code> ic(isolate()->builtins()->builtin(
1133 Builtins::LoadIC_Initialize)); 1136 Builtins::LoadIC_Initialize));
1134 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); 1137 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT);
1135 context()->Plug(eax); 1138 context()->Plug(eax);
1136 1139
1137 } else if (slot != NULL && slot->type() == Slot::LOOKUP) { 1140 } else if (slot != NULL && slot->type() == Slot::LOOKUP) {
1138 Label done, slow; 1141 Label done, slow;
1139 1142
1140 // Generate code for loading from variables potentially shadowed 1143 // Generate code for loading from variables potentially shadowed
1141 // by eval-introduced variables. 1144 // by eval-introduced variables.
1142 EmitDynamicLoadFromSlotFastCase(slot, NOT_INSIDE_TYPEOF, &slow, &done); 1145 EmitDynamicLoadFromSlotFastCase(slot, NOT_INSIDE_TYPEOF, &slow, &done);
(...skipping 10 matching lines...) Expand all
1153 } else if (slot != NULL) { 1156 } else if (slot != NULL) {
1154 Comment cmnt(masm_, (slot->type() == Slot::CONTEXT) 1157 Comment cmnt(masm_, (slot->type() == Slot::CONTEXT)
1155 ? "Context slot" 1158 ? "Context slot"
1156 : "Stack slot"); 1159 : "Stack slot");
1157 if (var->mode() == Variable::CONST) { 1160 if (var->mode() == Variable::CONST) {
1158 // Constants may be the hole value if they have not been initialized. 1161 // Constants may be the hole value if they have not been initialized.
1159 // Unhole them. 1162 // Unhole them.
1160 NearLabel done; 1163 NearLabel done;
1161 MemOperand slot_operand = EmitSlotSearch(slot, eax); 1164 MemOperand slot_operand = EmitSlotSearch(slot, eax);
1162 __ mov(eax, slot_operand); 1165 __ mov(eax, slot_operand);
1163 __ cmp(eax, FACTORY->the_hole_value()); 1166 __ cmp(eax, isolate()->factory()->the_hole_value());
1164 __ j(not_equal, &done); 1167 __ j(not_equal, &done);
1165 __ mov(eax, FACTORY->undefined_value()); 1168 __ mov(eax, isolate()->factory()->undefined_value());
1166 __ bind(&done); 1169 __ bind(&done);
1167 context()->Plug(eax); 1170 context()->Plug(eax);
1168 } else { 1171 } else {
1169 context()->Plug(slot); 1172 context()->Plug(slot);
1170 } 1173 }
1171 1174
1172 } else { 1175 } else {
1173 Comment cmnt(masm_, "Rewritten parameter"); 1176 Comment cmnt(masm_, "Rewritten parameter");
1174 ASSERT_NOT_NULL(property); 1177 ASSERT_NOT_NULL(property);
1175 // Rewritten parameter accesses are of the form "slot[literal]". 1178 // Rewritten parameter accesses are of the form "slot[literal]".
(...skipping 10 matching lines...) Expand all
1186 1189
1187 // Assert that the key is a smi. 1190 // Assert that the key is a smi.
1188 Literal* key_literal = property->key()->AsLiteral(); 1191 Literal* key_literal = property->key()->AsLiteral();
1189 ASSERT_NOT_NULL(key_literal); 1192 ASSERT_NOT_NULL(key_literal);
1190 ASSERT(key_literal->handle()->IsSmi()); 1193 ASSERT(key_literal->handle()->IsSmi());
1191 1194
1192 // Load the key. 1195 // Load the key.
1193 __ mov(eax, Immediate(key_literal->handle())); 1196 __ mov(eax, Immediate(key_literal->handle()));
1194 1197
1195 // Do a keyed property load. 1198 // Do a keyed property load.
1196 Handle<Code> ic(Isolate::Current()->builtins()->builtin( 1199 Handle<Code> ic(isolate()->builtins()->builtin(
1197 Builtins::KeyedLoadIC_Initialize)); 1200 Builtins::KeyedLoadIC_Initialize));
1198 EmitCallIC(ic, RelocInfo::CODE_TARGET); 1201 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1199 1202
1200 // Drop key and object left on the stack by IC. 1203 // Drop key and object left on the stack by IC.
1201 context()->Plug(eax); 1204 context()->Plug(eax);
1202 } 1205 }
1203 } 1206 }
1204 1207
1205 1208
1206 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { 1209 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
1207 Comment cmnt(masm_, "[ RegExpLiteral"); 1210 Comment cmnt(masm_, "[ RegExpLiteral");
1208 NearLabel materialized; 1211 NearLabel materialized;
1209 // Registers will be used as follows: 1212 // Registers will be used as follows:
1210 // edi = JS function. 1213 // edi = JS function.
1211 // ecx = literals array. 1214 // ecx = literals array.
1212 // ebx = regexp literal. 1215 // ebx = regexp literal.
1213 // eax = regexp literal clone. 1216 // eax = regexp literal clone.
1214 __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); 1217 __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
1215 __ mov(ecx, FieldOperand(edi, JSFunction::kLiteralsOffset)); 1218 __ mov(ecx, FieldOperand(edi, JSFunction::kLiteralsOffset));
1216 int literal_offset = 1219 int literal_offset =
1217 FixedArray::kHeaderSize + expr->literal_index() * kPointerSize; 1220 FixedArray::kHeaderSize + expr->literal_index() * kPointerSize;
1218 __ mov(ebx, FieldOperand(ecx, literal_offset)); 1221 __ mov(ebx, FieldOperand(ecx, literal_offset));
1219 __ cmp(ebx, FACTORY->undefined_value()); 1222 __ cmp(ebx, isolate()->factory()->undefined_value());
1220 __ j(not_equal, &materialized); 1223 __ j(not_equal, &materialized);
1221 1224
1222 // Create regexp literal using runtime function 1225 // Create regexp literal using runtime function
1223 // Result will be in eax. 1226 // Result will be in eax.
1224 __ push(ecx); 1227 __ push(ecx);
1225 __ push(Immediate(Smi::FromInt(expr->literal_index()))); 1228 __ push(Immediate(Smi::FromInt(expr->literal_index())));
1226 __ push(Immediate(expr->pattern())); 1229 __ push(Immediate(expr->pattern()));
1227 __ push(Immediate(expr->flags())); 1230 __ push(Immediate(expr->flags()));
1228 __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4); 1231 __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4);
1229 __ mov(ebx, eax); 1232 __ mov(ebx, eax);
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
1292 switch (property->kind()) { 1295 switch (property->kind()) {
1293 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1296 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1294 ASSERT(!CompileTimeValue::IsCompileTimeValue(value)); 1297 ASSERT(!CompileTimeValue::IsCompileTimeValue(value));
1295 // Fall through. 1298 // Fall through.
1296 case ObjectLiteral::Property::COMPUTED: 1299 case ObjectLiteral::Property::COMPUTED:
1297 if (key->handle()->IsSymbol()) { 1300 if (key->handle()->IsSymbol()) {
1298 if (property->emit_store()) { 1301 if (property->emit_store()) {
1299 VisitForAccumulatorValue(value); 1302 VisitForAccumulatorValue(value);
1300 __ mov(ecx, Immediate(key->handle())); 1303 __ mov(ecx, Immediate(key->handle()));
1301 __ mov(edx, Operand(esp, 0)); 1304 __ mov(edx, Operand(esp, 0));
1302 Handle<Code> ic(Isolate::Current()->builtins()->builtin( 1305 Handle<Code> ic(isolate()->builtins()->builtin(
1303 Builtins::StoreIC_Initialize)); 1306 Builtins::StoreIC_Initialize));
1304 EmitCallIC(ic, RelocInfo::CODE_TARGET); 1307 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1305 PrepareForBailoutForId(key->id(), NO_REGISTERS); 1308 PrepareForBailoutForId(key->id(), NO_REGISTERS);
1306 } else { 1309 } else {
1307 VisitForEffect(value); 1310 VisitForEffect(value);
1308 } 1311 }
1309 break; 1312 break;
1310 } 1313 }
1311 // Fall through. 1314 // Fall through.
1312 case ObjectLiteral::Property::PROTOTYPE: 1315 case ObjectLiteral::Property::PROTOTYPE:
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1344 void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { 1347 void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
1345 Comment cmnt(masm_, "[ ArrayLiteral"); 1348 Comment cmnt(masm_, "[ ArrayLiteral");
1346 1349
1347 ZoneList<Expression*>* subexprs = expr->values(); 1350 ZoneList<Expression*>* subexprs = expr->values();
1348 int length = subexprs->length(); 1351 int length = subexprs->length();
1349 1352
1350 __ mov(ebx, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); 1353 __ mov(ebx, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
1351 __ push(FieldOperand(ebx, JSFunction::kLiteralsOffset)); 1354 __ push(FieldOperand(ebx, JSFunction::kLiteralsOffset));
1352 __ push(Immediate(Smi::FromInt(expr->literal_index()))); 1355 __ push(Immediate(Smi::FromInt(expr->literal_index())));
1353 __ push(Immediate(expr->constant_elements())); 1356 __ push(Immediate(expr->constant_elements()));
1354 if (expr->constant_elements()->map() == HEAP->fixed_cow_array_map()) { 1357 if (expr->constant_elements()->map() ==
1358 isolate()->heap()->fixed_cow_array_map()) {
1355 ASSERT(expr->depth() == 1); 1359 ASSERT(expr->depth() == 1);
1356 FastCloneShallowArrayStub stub( 1360 FastCloneShallowArrayStub stub(
1357 FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS, length); 1361 FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS, length);
1358 __ CallStub(&stub); 1362 __ CallStub(&stub);
1359 __ IncrementCounter(COUNTERS->cow_arrays_created_stub(), 1); 1363 __ IncrementCounter(isolate()->counters()->cow_arrays_created_stub(), 1);
1360 } else if (expr->depth() > 1) { 1364 } else if (expr->depth() > 1) {
1361 __ CallRuntime(Runtime::kCreateArrayLiteral, 3); 1365 __ CallRuntime(Runtime::kCreateArrayLiteral, 3);
1362 } else if (length > FastCloneShallowArrayStub::kMaximumClonedLength) { 1366 } else if (length > FastCloneShallowArrayStub::kMaximumClonedLength) {
1363 __ CallRuntime(Runtime::kCreateArrayLiteralShallow, 3); 1367 __ CallRuntime(Runtime::kCreateArrayLiteralShallow, 3);
1364 } else { 1368 } else {
1365 FastCloneShallowArrayStub stub( 1369 FastCloneShallowArrayStub stub(
1366 FastCloneShallowArrayStub::CLONE_ELEMENTS, length); 1370 FastCloneShallowArrayStub::CLONE_ELEMENTS, length);
1367 __ CallStub(&stub); 1371 __ CallStub(&stub);
1368 } 1372 }
1369 1373
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
1535 EmitKeyedPropertyAssignment(expr); 1539 EmitKeyedPropertyAssignment(expr);
1536 break; 1540 break;
1537 } 1541 }
1538 } 1542 }
1539 1543
1540 1544
1541 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { 1545 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
1542 SetSourcePosition(prop->position()); 1546 SetSourcePosition(prop->position());
1543 Literal* key = prop->key()->AsLiteral(); 1547 Literal* key = prop->key()->AsLiteral();
1544 __ mov(ecx, Immediate(key->handle())); 1548 __ mov(ecx, Immediate(key->handle()));
1545 Handle<Code> ic(Isolate::Current()->builtins()->builtin( 1549 Handle<Code> ic(isolate()->builtins()->builtin(
1546 Builtins::LoadIC_Initialize)); 1550 Builtins::LoadIC_Initialize));
1547 EmitCallIC(ic, RelocInfo::CODE_TARGET); 1551 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1548 } 1552 }
1549 1553
1550 1554
1551 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { 1555 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
1552 SetSourcePosition(prop->position()); 1556 SetSourcePosition(prop->position());
1553 Handle<Code> ic(Isolate::Current()->builtins()->builtin( 1557 Handle<Code> ic(isolate()->builtins()->builtin(
1554 Builtins::KeyedLoadIC_Initialize)); 1558 Builtins::KeyedLoadIC_Initialize));
1555 EmitCallIC(ic, RelocInfo::CODE_TARGET); 1559 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1556 } 1560 }
1557 1561
1558 1562
1559 void FullCodeGenerator::EmitConstantSmiAdd(Expression* expr, 1563 void FullCodeGenerator::EmitConstantSmiAdd(Expression* expr,
1560 OverwriteMode mode, 1564 OverwriteMode mode,
1561 bool left_is_constant_smi, 1565 bool left_is_constant_smi,
1562 Smi* value) { 1566 Smi* value) {
1563 NearLabel call_stub; 1567 NearLabel call_stub;
(...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after
1882 EffectContext context(this); 1886 EffectContext context(this);
1883 EmitVariableAssignment(var, Token::ASSIGN); 1887 EmitVariableAssignment(var, Token::ASSIGN);
1884 break; 1888 break;
1885 } 1889 }
1886 case NAMED_PROPERTY: { 1890 case NAMED_PROPERTY: {
1887 __ push(eax); // Preserve value. 1891 __ push(eax); // Preserve value.
1888 VisitForAccumulatorValue(prop->obj()); 1892 VisitForAccumulatorValue(prop->obj());
1889 __ mov(edx, eax); 1893 __ mov(edx, eax);
1890 __ pop(eax); // Restore value. 1894 __ pop(eax); // Restore value.
1891 __ mov(ecx, prop->key()->AsLiteral()->handle()); 1895 __ mov(ecx, prop->key()->AsLiteral()->handle());
1892 Handle<Code> ic(Isolate::Current()->builtins()->builtin( 1896 Handle<Code> ic(isolate()->builtins()->builtin(
1893 Builtins::StoreIC_Initialize)); 1897 Builtins::StoreIC_Initialize));
1894 EmitCallIC(ic, RelocInfo::CODE_TARGET); 1898 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1895 break; 1899 break;
1896 } 1900 }
1897 case KEYED_PROPERTY: { 1901 case KEYED_PROPERTY: {
1898 __ push(eax); // Preserve value. 1902 __ push(eax); // Preserve value.
1899 VisitForStackValue(prop->obj()); 1903 VisitForStackValue(prop->obj());
1900 VisitForAccumulatorValue(prop->key()); 1904 VisitForAccumulatorValue(prop->key());
1901 __ mov(ecx, eax); 1905 __ mov(ecx, eax);
1902 __ pop(edx); 1906 __ pop(edx);
1903 __ pop(eax); // Restore value. 1907 __ pop(eax); // Restore value.
1904 Handle<Code> ic(Isolate::Current()->builtins()->builtin( 1908 Handle<Code> ic(isolate()->builtins()->builtin(
1905 Builtins::KeyedStoreIC_Initialize)); 1909 Builtins::KeyedStoreIC_Initialize));
1906 EmitCallIC(ic, RelocInfo::CODE_TARGET); 1910 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1907 break; 1911 break;
1908 } 1912 }
1909 } 1913 }
1910 } 1914 }
1911 1915
1912 1916
1913 void FullCodeGenerator::EmitVariableAssignment(Variable* var, 1917 void FullCodeGenerator::EmitVariableAssignment(Variable* var,
1914 Token::Value op) { 1918 Token::Value op) {
1915 // Left-hand sides that rewrite to explicit property accesses do not reach 1919 // Left-hand sides that rewrite to explicit property accesses do not reach
1916 // here. 1920 // here.
1917 ASSERT(var != NULL); 1921 ASSERT(var != NULL);
1918 ASSERT(var->is_global() || var->AsSlot() != NULL); 1922 ASSERT(var->is_global() || var->AsSlot() != NULL);
1919 1923
1920 if (var->is_global()) { 1924 if (var->is_global()) {
1921 ASSERT(!var->is_this()); 1925 ASSERT(!var->is_this());
1922 // Assignment to a global variable. Use inline caching for the 1926 // Assignment to a global variable. Use inline caching for the
1923 // assignment. Right-hand-side value is passed in eax, variable name in 1927 // assignment. Right-hand-side value is passed in eax, variable name in
1924 // ecx, and the global object on the stack. 1928 // ecx, and the global object on the stack.
1925 __ mov(ecx, var->name()); 1929 __ mov(ecx, var->name());
1926 __ mov(edx, GlobalObjectOperand()); 1930 __ mov(edx, GlobalObjectOperand());
1927 Handle<Code> ic(Isolate::Current()->builtins()->builtin( 1931 Handle<Code> ic(isolate()->builtins()->builtin(
1928 Builtins::StoreIC_Initialize)); 1932 Builtins::StoreIC_Initialize));
1929 EmitCallIC(ic, RelocInfo::CODE_TARGET); 1933 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1930 1934
1931 } else if (var->mode() != Variable::CONST || op == Token::INIT_CONST) { 1935 } else if (var->mode() != Variable::CONST || op == Token::INIT_CONST) {
1932 // Perform the assignment for non-const variables and for initialization 1936 // Perform the assignment for non-const variables and for initialization
1933 // of const variables. Const assignments are simply skipped. 1937 // of const variables. Const assignments are simply skipped.
1934 Label done; 1938 Label done;
1935 Slot* slot = var->AsSlot(); 1939 Slot* slot = var->AsSlot();
1936 switch (slot->type()) { 1940 switch (slot->type()) {
1937 case Slot::PARAMETER: 1941 case Slot::PARAMETER:
1938 case Slot::LOCAL: 1942 case Slot::LOCAL:
1939 if (op == Token::INIT_CONST) { 1943 if (op == Token::INIT_CONST) {
1940 // Detect const reinitialization by checking for the hole value. 1944 // Detect const reinitialization by checking for the hole value.
1941 __ mov(edx, Operand(ebp, SlotOffset(slot))); 1945 __ mov(edx, Operand(ebp, SlotOffset(slot)));
1942 __ cmp(edx, FACTORY->the_hole_value()); 1946 __ cmp(edx, isolate()->factory()->the_hole_value());
1943 __ j(not_equal, &done); 1947 __ j(not_equal, &done);
1944 } 1948 }
1945 // Perform the assignment. 1949 // Perform the assignment.
1946 __ mov(Operand(ebp, SlotOffset(slot)), eax); 1950 __ mov(Operand(ebp, SlotOffset(slot)), eax);
1947 break; 1951 break;
1948 1952
1949 case Slot::CONTEXT: { 1953 case Slot::CONTEXT: {
1950 MemOperand target = EmitSlotSearch(slot, ecx); 1954 MemOperand target = EmitSlotSearch(slot, ecx);
1951 if (op == Token::INIT_CONST) { 1955 if (op == Token::INIT_CONST) {
1952 // Detect const reinitialization by checking for the hole value. 1956 // Detect const reinitialization by checking for the hole value.
1953 __ mov(edx, target); 1957 __ mov(edx, target);
1954 __ cmp(edx, FACTORY->the_hole_value()); 1958 __ cmp(edx, isolate()->factory()->the_hole_value());
1955 __ j(not_equal, &done); 1959 __ j(not_equal, &done);
1956 } 1960 }
1957 // Perform the assignment and issue the write barrier. 1961 // Perform the assignment and issue the write barrier.
1958 __ mov(target, eax); 1962 __ mov(target, eax);
1959 // The value of the assignment is in eax. RecordWrite clobbers its 1963 // The value of the assignment is in eax. RecordWrite clobbers its
1960 // register arguments. 1964 // register arguments.
1961 __ mov(edx, eax); 1965 __ mov(edx, eax);
1962 int offset = FixedArray::kHeaderSize + slot->index() * kPointerSize; 1966 int offset = FixedArray::kHeaderSize + slot->index() * kPointerSize;
1963 __ RecordWrite(ecx, offset, edx, ebx); 1967 __ RecordWrite(ecx, offset, edx, ebx);
1964 break; 1968 break;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
2002 } 2006 }
2003 2007
2004 // Record source code position before IC call. 2008 // Record source code position before IC call.
2005 SetSourcePosition(expr->position()); 2009 SetSourcePosition(expr->position());
2006 __ mov(ecx, prop->key()->AsLiteral()->handle()); 2010 __ mov(ecx, prop->key()->AsLiteral()->handle());
2007 if (expr->ends_initialization_block()) { 2011 if (expr->ends_initialization_block()) {
2008 __ mov(edx, Operand(esp, 0)); 2012 __ mov(edx, Operand(esp, 0));
2009 } else { 2013 } else {
2010 __ pop(edx); 2014 __ pop(edx);
2011 } 2015 }
2012 Handle<Code> ic(Isolate::Current()->builtins()->builtin( 2016 Handle<Code> ic(isolate()->builtins()->builtin(
2013 Builtins::StoreIC_Initialize)); 2017 Builtins::StoreIC_Initialize));
2014 EmitCallIC(ic, RelocInfo::CODE_TARGET); 2018 EmitCallIC(ic, RelocInfo::CODE_TARGET);
2015 2019
2016 // If the assignment ends an initialization block, revert to fast case. 2020 // If the assignment ends an initialization block, revert to fast case.
2017 if (expr->ends_initialization_block()) { 2021 if (expr->ends_initialization_block()) {
2018 __ push(eax); // Result of assignment, saved even if not needed. 2022 __ push(eax); // Result of assignment, saved even if not needed.
2019 __ push(Operand(esp, kPointerSize)); // Receiver is under value. 2023 __ push(Operand(esp, kPointerSize)); // Receiver is under value.
2020 __ CallRuntime(Runtime::kToFastProperties, 1); 2024 __ CallRuntime(Runtime::kToFastProperties, 1);
2021 __ pop(eax); 2025 __ pop(eax);
2022 context()->DropAndPlug(1, eax); 2026 context()->DropAndPlug(1, eax);
(...skipping 18 matching lines...) Expand all
2041 } 2045 }
2042 2046
2043 __ pop(ecx); 2047 __ pop(ecx);
2044 if (expr->ends_initialization_block()) { 2048 if (expr->ends_initialization_block()) {
2045 __ mov(edx, Operand(esp, 0)); // Leave receiver on the stack for later. 2049 __ mov(edx, Operand(esp, 0)); // Leave receiver on the stack for later.
2046 } else { 2050 } else {
2047 __ pop(edx); 2051 __ pop(edx);
2048 } 2052 }
2049 // Record source code position before IC call. 2053 // Record source code position before IC call.
2050 SetSourcePosition(expr->position()); 2054 SetSourcePosition(expr->position());
2051 Handle<Code> ic(Isolate::Current()->builtins()->builtin( 2055 Handle<Code> ic(isolate()->builtins()->builtin(
2052 Builtins::KeyedStoreIC_Initialize)); 2056 Builtins::KeyedStoreIC_Initialize));
2053 EmitCallIC(ic, RelocInfo::CODE_TARGET); 2057 EmitCallIC(ic, RelocInfo::CODE_TARGET);
2054 2058
2055 // If the assignment ends an initialization block, revert to fast case. 2059 // If the assignment ends an initialization block, revert to fast case.
2056 if (expr->ends_initialization_block()) { 2060 if (expr->ends_initialization_block()) {
2057 __ pop(edx); 2061 __ pop(edx);
2058 __ push(eax); // Result of assignment, saved even if not needed. 2062 __ push(eax); // Result of assignment, saved even if not needed.
2059 __ push(edx); 2063 __ push(edx);
2060 __ CallRuntime(Runtime::kToFastProperties, 1); 2064 __ CallRuntime(Runtime::kToFastProperties, 1);
2061 __ pop(eax); 2065 __ pop(eax);
(...skipping 29 matching lines...) Expand all
2091 int arg_count = args->length(); 2095 int arg_count = args->length();
2092 { PreservePositionScope scope(masm()->positions_recorder()); 2096 { PreservePositionScope scope(masm()->positions_recorder());
2093 for (int i = 0; i < arg_count; i++) { 2097 for (int i = 0; i < arg_count; i++) {
2094 VisitForStackValue(args->at(i)); 2098 VisitForStackValue(args->at(i));
2095 } 2099 }
2096 __ Set(ecx, Immediate(name)); 2100 __ Set(ecx, Immediate(name));
2097 } 2101 }
2098 // Record source position of the IC call. 2102 // Record source position of the IC call.
2099 SetSourcePosition(expr->position()); 2103 SetSourcePosition(expr->position());
2100 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; 2104 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
2101 Handle<Code> ic = ISOLATE->stub_cache()->ComputeCallInitialize(arg_count, 2105 Handle<Code> ic = isolate()->stub_cache()->ComputeCallInitialize(
2102 in_loop); 2106 arg_count, in_loop);
2103 EmitCallIC(ic, mode); 2107 EmitCallIC(ic, mode);
2104 RecordJSReturnSite(expr); 2108 RecordJSReturnSite(expr);
2105 // Restore context register. 2109 // Restore context register.
2106 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2110 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2107 context()->Plug(eax); 2111 context()->Plug(eax);
2108 } 2112 }
2109 2113
2110 2114
2111 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, 2115 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr,
2112 Expression* key, 2116 Expression* key,
(...skipping 11 matching lines...) Expand all
2124 ZoneList<Expression*>* args = expr->arguments(); 2128 ZoneList<Expression*>* args = expr->arguments();
2125 int arg_count = args->length(); 2129 int arg_count = args->length();
2126 { PreservePositionScope scope(masm()->positions_recorder()); 2130 { PreservePositionScope scope(masm()->positions_recorder());
2127 for (int i = 0; i < arg_count; i++) { 2131 for (int i = 0; i < arg_count; i++) {
2128 VisitForStackValue(args->at(i)); 2132 VisitForStackValue(args->at(i));
2129 } 2133 }
2130 } 2134 }
2131 // Record source position of the IC call. 2135 // Record source position of the IC call.
2132 SetSourcePosition(expr->position()); 2136 SetSourcePosition(expr->position());
2133 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; 2137 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
2134 Handle<Code> ic = ISOLATE->stub_cache()->ComputeKeyedCallInitialize(arg_count, 2138 Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedCallInitialize(
2135 in_loop); 2139 arg_count, in_loop);
2136 __ mov(ecx, Operand(esp, (arg_count + 1) * kPointerSize)); // Key. 2140 __ mov(ecx, Operand(esp, (arg_count + 1) * kPointerSize)); // Key.
2137 EmitCallIC(ic, mode); 2141 EmitCallIC(ic, mode);
2138 RecordJSReturnSite(expr); 2142 RecordJSReturnSite(expr);
2139 // Restore context register. 2143 // Restore context register.
2140 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2144 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2141 context()->DropAndPlug(1, eax); // Drop the key still on the stack. 2145 context()->DropAndPlug(1, eax); // Drop the key still on the stack.
2142 } 2146 }
2143 2147
2144 2148
2145 void FullCodeGenerator::EmitCallWithStub(Call* expr) { 2149 void FullCodeGenerator::EmitCallWithStub(Call* expr) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
2177 if (var != NULL && var->is_possibly_eval()) { 2181 if (var != NULL && var->is_possibly_eval()) {
2178 // In a call to eval, we first call %ResolvePossiblyDirectEval to 2182 // In a call to eval, we first call %ResolvePossiblyDirectEval to
2179 // resolve the function we need to call and the receiver of the 2183 // resolve the function we need to call and the receiver of the
2180 // call. Then we call the resolved function using the given 2184 // call. Then we call the resolved function using the given
2181 // arguments. 2185 // arguments.
2182 ZoneList<Expression*>* args = expr->arguments(); 2186 ZoneList<Expression*>* args = expr->arguments();
2183 int arg_count = args->length(); 2187 int arg_count = args->length();
2184 { PreservePositionScope pos_scope(masm()->positions_recorder()); 2188 { PreservePositionScope pos_scope(masm()->positions_recorder());
2185 VisitForStackValue(fun); 2189 VisitForStackValue(fun);
2186 // Reserved receiver slot. 2190 // Reserved receiver slot.
2187 __ push(Immediate(FACTORY->undefined_value())); 2191 __ push(Immediate(isolate()->factory()->undefined_value()));
2188 2192
2189 // Push the arguments. 2193 // Push the arguments.
2190 for (int i = 0; i < arg_count; i++) { 2194 for (int i = 0; i < arg_count; i++) {
2191 VisitForStackValue(args->at(i)); 2195 VisitForStackValue(args->at(i));
2192 } 2196 }
2193 2197
2194 // Push copy of the function - found below the arguments. 2198 // Push copy of the function - found below the arguments.
2195 __ push(Operand(esp, (arg_count + 1) * kPointerSize)); 2199 __ push(Operand(esp, (arg_count + 1) * kPointerSize));
2196 2200
2197 // Push copy of the first argument or undefined if it doesn't exist. 2201 // Push copy of the first argument or undefined if it doesn't exist.
2198 if (arg_count > 0) { 2202 if (arg_count > 0) {
2199 __ push(Operand(esp, arg_count * kPointerSize)); 2203 __ push(Operand(esp, arg_count * kPointerSize));
2200 } else { 2204 } else {
2201 __ push(Immediate(FACTORY->undefined_value())); 2205 __ push(Immediate(isolate()->factory()->undefined_value()));
2202 } 2206 }
2203 2207
2204 // Push the receiver of the enclosing function and do runtime call. 2208 // Push the receiver of the enclosing function and do runtime call.
2205 __ push(Operand(ebp, (2 + scope()->num_parameters()) * kPointerSize)); 2209 __ push(Operand(ebp, (2 + scope()->num_parameters()) * kPointerSize));
2206 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 3); 2210 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 3);
2207 2211
2208 // The runtime call returns a pair of values in eax (function) and 2212 // The runtime call returns a pair of values in eax (function) and
2209 // edx (receiver). Touch up the stack with the right values. 2213 // edx (receiver). Touch up the stack with the right values.
2210 __ mov(Operand(esp, (arg_count + 0) * kPointerSize), edx); 2214 __ mov(Operand(esp, (arg_count + 0) * kPointerSize), edx);
2211 __ mov(Operand(esp, (arg_count + 1) * kPointerSize), eax); 2215 __ mov(Operand(esp, (arg_count + 1) * kPointerSize), eax);
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
2278 VisitForStackValue(prop->obj()); 2282 VisitForStackValue(prop->obj());
2279 } 2283 }
2280 if (prop->is_synthetic()) { 2284 if (prop->is_synthetic()) {
2281 { PreservePositionScope scope(masm()->positions_recorder()); 2285 { PreservePositionScope scope(masm()->positions_recorder());
2282 VisitForAccumulatorValue(prop->key()); 2286 VisitForAccumulatorValue(prop->key());
2283 } 2287 }
2284 // Record source code position for IC call. 2288 // Record source code position for IC call.
2285 SetSourcePosition(prop->position()); 2289 SetSourcePosition(prop->position());
2286 __ pop(edx); // We do not need to keep the receiver. 2290 __ pop(edx); // We do not need to keep the receiver.
2287 2291
2288 Handle<Code> ic(Isolate::Current()->builtins()->builtin( 2292 Handle<Code> ic(isolate()->builtins()->builtin(
2289 Builtins::KeyedLoadIC_Initialize)); 2293 Builtins::KeyedLoadIC_Initialize));
2290 EmitCallIC(ic, RelocInfo::CODE_TARGET); 2294 EmitCallIC(ic, RelocInfo::CODE_TARGET);
2291 // Push result (function). 2295 // Push result (function).
2292 __ push(eax); 2296 __ push(eax);
2293 // Push Global receiver. 2297 // Push Global receiver.
2294 __ mov(ecx, GlobalObjectOperand()); 2298 __ mov(ecx, GlobalObjectOperand());
2295 __ push(FieldOperand(ecx, GlobalObject::kGlobalReceiverOffset)); 2299 __ push(FieldOperand(ecx, GlobalObject::kGlobalReceiverOffset));
2296 EmitCallWithStub(expr); 2300 EmitCallWithStub(expr);
2297 } else { 2301 } else {
2298 EmitKeyedCallWithIC(expr, prop->key(), RelocInfo::CODE_TARGET); 2302 EmitKeyedCallWithIC(expr, prop->key(), RelocInfo::CODE_TARGET);
2299 } 2303 }
2300 } 2304 }
2301 } else { 2305 } else {
2302 // Call to some other expression. If the expression is an anonymous 2306 // Call to some other expression. If the expression is an anonymous
2303 // function literal not called in a loop, mark it as one that should 2307 // function literal not called in a loop, mark it as one that should
2304 // also use the full code generator. 2308 // also use the full code generator.
2305 FunctionLiteral* lit = fun->AsFunctionLiteral(); 2309 FunctionLiteral* lit = fun->AsFunctionLiteral();
2306 if (lit != NULL && 2310 if (lit != NULL &&
2307 lit->name()->Equals(HEAP->empty_string()) && 2311 lit->name()->Equals(isolate()->heap()->empty_string()) &&
2308 loop_depth() == 0) { 2312 loop_depth() == 0) {
2309 lit->set_try_full_codegen(true); 2313 lit->set_try_full_codegen(true);
2310 } 2314 }
2311 { PreservePositionScope scope(masm()->positions_recorder()); 2315 { PreservePositionScope scope(masm()->positions_recorder());
2312 VisitForStackValue(fun); 2316 VisitForStackValue(fun);
2313 } 2317 }
2314 // Load global receiver object. 2318 // Load global receiver object.
2315 __ mov(ebx, GlobalObjectOperand()); 2319 __ mov(ebx, GlobalObjectOperand());
2316 __ push(FieldOperand(ebx, GlobalObject::kGlobalReceiverOffset)); 2320 __ push(FieldOperand(ebx, GlobalObject::kGlobalReceiverOffset));
2317 // Emit function call. 2321 // Emit function call.
(...skipping 26 matching lines...) Expand all
2344 } 2348 }
2345 2349
2346 // Call the construct call builtin that handles allocation and 2350 // Call the construct call builtin that handles allocation and
2347 // constructor invocation. 2351 // constructor invocation.
2348 SetSourcePosition(expr->position()); 2352 SetSourcePosition(expr->position());
2349 2353
2350 // Load function and argument count into edi and eax. 2354 // Load function and argument count into edi and eax.
2351 __ Set(eax, Immediate(arg_count)); 2355 __ Set(eax, Immediate(arg_count));
2352 __ mov(edi, Operand(esp, arg_count * kPointerSize)); 2356 __ mov(edi, Operand(esp, arg_count * kPointerSize));
2353 2357
2354 Handle<Code> construct_builtin(Isolate::Current()->builtins()->builtin( 2358 Handle<Code> construct_builtin(isolate()->builtins()->builtin(
2355 Builtins::JSConstructCall)); 2359 Builtins::JSConstructCall));
2356 __ call(construct_builtin, RelocInfo::CONSTRUCT_CALL); 2360 __ call(construct_builtin, RelocInfo::CONSTRUCT_CALL);
2357 context()->Plug(eax); 2361 context()->Plug(eax);
2358 } 2362 }
2359 2363
2360 2364
2361 void FullCodeGenerator::EmitIsSmi(ZoneList<Expression*>* args) { 2365 void FullCodeGenerator::EmitIsSmi(ZoneList<Expression*>* args) {
2362 ASSERT(args->length() == 1); 2366 ASSERT(args->length() == 1);
2363 2367
2364 VisitForAccumulatorValue(args->at(0)); 2368 VisitForAccumulatorValue(args->at(0));
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
2405 2409
2406 Label materialize_true, materialize_false; 2410 Label materialize_true, materialize_false;
2407 Label* if_true = NULL; 2411 Label* if_true = NULL;
2408 Label* if_false = NULL; 2412 Label* if_false = NULL;
2409 Label* fall_through = NULL; 2413 Label* fall_through = NULL;
2410 context()->PrepareTest(&materialize_true, &materialize_false, 2414 context()->PrepareTest(&materialize_true, &materialize_false,
2411 &if_true, &if_false, &fall_through); 2415 &if_true, &if_false, &fall_through);
2412 2416
2413 __ test(eax, Immediate(kSmiTagMask)); 2417 __ test(eax, Immediate(kSmiTagMask));
2414 __ j(zero, if_false); 2418 __ j(zero, if_false);
2415 __ cmp(eax, FACTORY->null_value()); 2419 __ cmp(eax, isolate()->factory()->null_value());
2416 __ j(equal, if_true); 2420 __ j(equal, if_true);
2417 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset)); 2421 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
2418 // Undetectable objects behave like undefined when tested with typeof. 2422 // Undetectable objects behave like undefined when tested with typeof.
2419 __ movzx_b(ecx, FieldOperand(ebx, Map::kBitFieldOffset)); 2423 __ movzx_b(ecx, FieldOperand(ebx, Map::kBitFieldOffset));
2420 __ test(ecx, Immediate(1 << Map::kIsUndetectable)); 2424 __ test(ecx, Immediate(1 << Map::kIsUndetectable));
2421 __ j(not_zero, if_false); 2425 __ j(not_zero, if_false);
2422 __ movzx_b(ecx, FieldOperand(ebx, Map::kInstanceTypeOffset)); 2426 __ movzx_b(ecx, FieldOperand(ebx, Map::kInstanceTypeOffset));
2423 __ cmp(ecx, FIRST_JS_OBJECT_TYPE); 2427 __ cmp(ecx, FIRST_JS_OBJECT_TYPE);
2424 __ j(below, if_false); 2428 __ j(below, if_false);
2425 __ cmp(ecx, LAST_JS_OBJECT_TYPE); 2429 __ cmp(ecx, LAST_JS_OBJECT_TYPE);
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after
2684 __ j(not_equal, &non_function_constructor); 2688 __ j(not_equal, &non_function_constructor);
2685 2689
2686 // eax now contains the constructor function. Grab the 2690 // eax now contains the constructor function. Grab the
2687 // instance class name from there. 2691 // instance class name from there.
2688 __ mov(eax, FieldOperand(eax, JSFunction::kSharedFunctionInfoOffset)); 2692 __ mov(eax, FieldOperand(eax, JSFunction::kSharedFunctionInfoOffset));
2689 __ mov(eax, FieldOperand(eax, SharedFunctionInfo::kInstanceClassNameOffset)); 2693 __ mov(eax, FieldOperand(eax, SharedFunctionInfo::kInstanceClassNameOffset));
2690 __ jmp(&done); 2694 __ jmp(&done);
2691 2695
2692 // Functions have class 'Function'. 2696 // Functions have class 'Function'.
2693 __ bind(&function); 2697 __ bind(&function);
2694 __ mov(eax, FACTORY->function_class_symbol()); 2698 __ mov(eax, isolate()->factory()->function_class_symbol());
2695 __ jmp(&done); 2699 __ jmp(&done);
2696 2700
2697 // Objects with a non-function constructor have class 'Object'. 2701 // Objects with a non-function constructor have class 'Object'.
2698 __ bind(&non_function_constructor); 2702 __ bind(&non_function_constructor);
2699 __ mov(eax, FACTORY->Object_symbol()); 2703 __ mov(eax, isolate()->factory()->Object_symbol());
2700 __ jmp(&done); 2704 __ jmp(&done);
2701 2705
2702 // Non-JS objects have class null. 2706 // Non-JS objects have class null.
2703 __ bind(&null); 2707 __ bind(&null);
2704 __ mov(eax, FACTORY->null_value()); 2708 __ mov(eax, isolate()->factory()->null_value());
2705 2709
2706 // All done. 2710 // All done.
2707 __ bind(&done); 2711 __ bind(&done);
2708 2712
2709 context()->Plug(eax); 2713 context()->Plug(eax);
2710 } 2714 }
2711 2715
2712 2716
2713 void FullCodeGenerator::EmitLog(ZoneList<Expression*>* args) { 2717 void FullCodeGenerator::EmitLog(ZoneList<Expression*>* args) {
2714 // Conditionally generate a log call. 2718 // Conditionally generate a log call.
2715 // Args: 2719 // Args:
2716 // 0 (literal string): The type of logging (corresponds to the flags). 2720 // 0 (literal string): The type of logging (corresponds to the flags).
2717 // This is used to determine whether or not to generate the log call. 2721 // This is used to determine whether or not to generate the log call.
2718 // 1 (string): Format string. Access the string at argument index 2 2722 // 1 (string): Format string. Access the string at argument index 2
2719 // with '%2s' (see Logger::LogRuntime for all the formats). 2723 // with '%2s' (see Logger::LogRuntime for all the formats).
2720 // 2 (array): Arguments to the format string. 2724 // 2 (array): Arguments to the format string.
2721 ASSERT_EQ(args->length(), 3); 2725 ASSERT_EQ(args->length(), 3);
2722 #ifdef ENABLE_LOGGING_AND_PROFILING 2726 #ifdef ENABLE_LOGGING_AND_PROFILING
2723 if (CodeGenerator::ShouldGenerateLog(args->at(0))) { 2727 if (CodeGenerator::ShouldGenerateLog(args->at(0))) {
2724 VisitForStackValue(args->at(1)); 2728 VisitForStackValue(args->at(1));
2725 VisitForStackValue(args->at(2)); 2729 VisitForStackValue(args->at(2));
2726 __ CallRuntime(Runtime::kLog, 2); 2730 __ CallRuntime(Runtime::kLog, 2);
2727 } 2731 }
2728 #endif 2732 #endif
2729 // Finally, we're expected to leave a value on the top of the stack. 2733 // Finally, we're expected to leave a value on the top of the stack.
2730 __ mov(eax, FACTORY->undefined_value()); 2734 __ mov(eax, isolate()->factory()->undefined_value());
2731 context()->Plug(eax); 2735 context()->Plug(eax);
2732 } 2736 }
2733 2737
2734 2738
2735 void FullCodeGenerator::EmitRandomHeapNumber(ZoneList<Expression*>* args) { 2739 void FullCodeGenerator::EmitRandomHeapNumber(ZoneList<Expression*>* args) {
2736 ASSERT(args->length() == 0); 2740 ASSERT(args->length() == 0);
2737 2741
2738 Label slow_allocate_heapnumber; 2742 Label slow_allocate_heapnumber;
2739 Label heapnumber_allocated; 2743 Label heapnumber_allocated;
2740 2744
2741 __ AllocateHeapNumber(edi, ebx, ecx, &slow_allocate_heapnumber); 2745 __ AllocateHeapNumber(edi, ebx, ecx, &slow_allocate_heapnumber);
2742 __ jmp(&heapnumber_allocated); 2746 __ jmp(&heapnumber_allocated);
2743 2747
2744 __ bind(&slow_allocate_heapnumber); 2748 __ bind(&slow_allocate_heapnumber);
2745 // Allocate a heap number. 2749 // Allocate a heap number.
2746 __ CallRuntime(Runtime::kNumberAlloc, 0); 2750 __ CallRuntime(Runtime::kNumberAlloc, 0);
2747 __ mov(edi, eax); 2751 __ mov(edi, eax);
2748 2752
2749 __ bind(&heapnumber_allocated); 2753 __ bind(&heapnumber_allocated);
2750 2754
2751 __ PrepareCallCFunction(0, ebx); 2755 __ PrepareCallCFunction(0, ebx);
2752 __ CallCFunction(ExternalReference::random_uint32_function(), 0); 2756 __ CallCFunction(ExternalReference::random_uint32_function(), 0);
2753 2757
2754 // Convert 32 random bits in eax to 0.(32 random bits) in a double 2758 // Convert 32 random bits in eax to 0.(32 random bits) in a double
2755 // by computing: 2759 // by computing:
2756 // ( 1.(20 0s)(32 random bits) x 2^20 ) - (1.0 x 2^20)). 2760 // ( 1.(20 0s)(32 random bits) x 2^20 ) - (1.0 x 2^20)).
2757 // This is implemented on both SSE2 and FPU. 2761 // This is implemented on both SSE2 and FPU.
2758 if (Isolate::Current()->cpu_features()->IsSupported(SSE2)) { 2762 if (isolate()->cpu_features()->IsSupported(SSE2)) {
2759 CpuFeatures::Scope fscope(SSE2); 2763 CpuFeatures::Scope fscope(SSE2);
2760 __ mov(ebx, Immediate(0x49800000)); // 1.0 x 2^20 as single. 2764 __ mov(ebx, Immediate(0x49800000)); // 1.0 x 2^20 as single.
2761 __ movd(xmm1, Operand(ebx)); 2765 __ movd(xmm1, Operand(ebx));
2762 __ movd(xmm0, Operand(eax)); 2766 __ movd(xmm0, Operand(eax));
2763 __ cvtss2sd(xmm1, xmm1); 2767 __ cvtss2sd(xmm1, xmm1);
2764 __ pxor(xmm0, xmm1); 2768 __ pxor(xmm0, xmm1);
2765 __ subsd(xmm0, xmm1); 2769 __ subsd(xmm0, xmm1);
2766 __ movdbl(FieldOperand(edi, HeapNumber::kValueOffset), xmm0); 2770 __ movdbl(FieldOperand(edi, HeapNumber::kValueOffset), xmm0);
2767 } else { 2771 } else {
2768 // 0x4130000000000000 is 1.0 x 2^20 as a double. 2772 // 0x4130000000000000 is 1.0 x 2^20 as a double.
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
2917 &need_conversion, 2921 &need_conversion,
2918 &need_conversion, 2922 &need_conversion,
2919 &index_out_of_range, 2923 &index_out_of_range,
2920 STRING_INDEX_IS_NUMBER); 2924 STRING_INDEX_IS_NUMBER);
2921 generator.GenerateFast(masm_); 2925 generator.GenerateFast(masm_);
2922 __ jmp(&done); 2926 __ jmp(&done);
2923 2927
2924 __ bind(&index_out_of_range); 2928 __ bind(&index_out_of_range);
2925 // When the index is out of range, the spec requires us to return 2929 // When the index is out of range, the spec requires us to return
2926 // NaN. 2930 // NaN.
2927 __ Set(result, Immediate(FACTORY->nan_value())); 2931 __ Set(result, Immediate(isolate()->factory()->nan_value()));
2928 __ jmp(&done); 2932 __ jmp(&done);
2929 2933
2930 __ bind(&need_conversion); 2934 __ bind(&need_conversion);
2931 // Move the undefined value into the result register, which will 2935 // Move the undefined value into the result register, which will
2932 // trigger conversion. 2936 // trigger conversion.
2933 __ Set(result, Immediate(FACTORY->undefined_value())); 2937 __ Set(result, Immediate(isolate()->factory()->undefined_value()));
2934 __ jmp(&done); 2938 __ jmp(&done);
2935 2939
2936 NopRuntimeCallHelper call_helper; 2940 NopRuntimeCallHelper call_helper;
2937 generator.GenerateSlow(masm_, call_helper); 2941 generator.GenerateSlow(masm_, call_helper);
2938 2942
2939 __ bind(&done); 2943 __ bind(&done);
2940 context()->Plug(result); 2944 context()->Plug(result);
2941 } 2945 }
2942 2946
2943 2947
(...skipping 22 matching lines...) Expand all
2966 &need_conversion, 2970 &need_conversion,
2967 &need_conversion, 2971 &need_conversion,
2968 &index_out_of_range, 2972 &index_out_of_range,
2969 STRING_INDEX_IS_NUMBER); 2973 STRING_INDEX_IS_NUMBER);
2970 generator.GenerateFast(masm_); 2974 generator.GenerateFast(masm_);
2971 __ jmp(&done); 2975 __ jmp(&done);
2972 2976
2973 __ bind(&index_out_of_range); 2977 __ bind(&index_out_of_range);
2974 // When the index is out of range, the spec requires us to return 2978 // When the index is out of range, the spec requires us to return
2975 // the empty string. 2979 // the empty string.
2976 __ Set(result, Immediate(FACTORY->empty_string())); 2980 __ Set(result, Immediate(isolate()->factory()->empty_string()));
2977 __ jmp(&done); 2981 __ jmp(&done);
2978 2982
2979 __ bind(&need_conversion); 2983 __ bind(&need_conversion);
2980 // Move smi zero into the result register, which will trigger 2984 // Move smi zero into the result register, which will trigger
2981 // conversion. 2985 // conversion.
2982 __ Set(result, Immediate(Smi::FromInt(0))); 2986 __ Set(result, Immediate(Smi::FromInt(0)));
2983 __ jmp(&done); 2987 __ jmp(&done);
2984 2988
2985 NopRuntimeCallHelper call_helper; 2989 NopRuntimeCallHelper call_helper;
2986 generator.GenerateSlow(masm_, call_helper); 2990 generator.GenerateSlow(masm_, call_helper);
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
3102 // has no indexed interceptor. 3106 // has no indexed interceptor.
3103 __ CmpObjectType(object, FIRST_JS_OBJECT_TYPE, temp); 3107 __ CmpObjectType(object, FIRST_JS_OBJECT_TYPE, temp);
3104 __ j(below, &slow_case); 3108 __ j(below, &slow_case);
3105 __ test_b(FieldOperand(temp, Map::kBitFieldOffset), 3109 __ test_b(FieldOperand(temp, Map::kBitFieldOffset),
3106 KeyedLoadIC::kSlowCaseBitFieldMask); 3110 KeyedLoadIC::kSlowCaseBitFieldMask);
3107 __ j(not_zero, &slow_case); 3111 __ j(not_zero, &slow_case);
3108 3112
3109 // Check the object's elements are in fast case and writable. 3113 // Check the object's elements are in fast case and writable.
3110 __ mov(elements, FieldOperand(object, JSObject::kElementsOffset)); 3114 __ mov(elements, FieldOperand(object, JSObject::kElementsOffset));
3111 __ cmp(FieldOperand(elements, HeapObject::kMapOffset), 3115 __ cmp(FieldOperand(elements, HeapObject::kMapOffset),
3112 Immediate(FACTORY->fixed_array_map())); 3116 Immediate(isolate()->factory()->fixed_array_map()));
3113 __ j(not_equal, &slow_case); 3117 __ j(not_equal, &slow_case);
3114 3118
3115 // Check that both indices are smis. 3119 // Check that both indices are smis.
3116 __ mov(index_1, Operand(esp, 1 * kPointerSize)); 3120 __ mov(index_1, Operand(esp, 1 * kPointerSize));
3117 __ mov(index_2, Operand(esp, 0)); 3121 __ mov(index_2, Operand(esp, 0));
3118 __ mov(temp, index_1); 3122 __ mov(temp, index_1);
3119 __ or_(temp, Operand(index_2)); 3123 __ or_(temp, Operand(index_2));
3120 __ test(temp, Immediate(kSmiTagMask)); 3124 __ test(temp, Immediate(kSmiTagMask));
3121 __ j(not_zero, &slow_case); 3125 __ j(not_zero, &slow_case);
3122 3126
(...skipping 10 matching lines...) Expand all
3133 Label new_space; 3137 Label new_space;
3134 __ InNewSpace(elements, temp, equal, &new_space); 3138 __ InNewSpace(elements, temp, equal, &new_space);
3135 3139
3136 __ mov(object, elements); 3140 __ mov(object, elements);
3137 __ RecordWriteHelper(object, index_1, temp); 3141 __ RecordWriteHelper(object, index_1, temp);
3138 __ RecordWriteHelper(elements, index_2, temp); 3142 __ RecordWriteHelper(elements, index_2, temp);
3139 3143
3140 __ bind(&new_space); 3144 __ bind(&new_space);
3141 // We are done. Drop elements from the stack, and return undefined. 3145 // We are done. Drop elements from the stack, and return undefined.
3142 __ add(Operand(esp), Immediate(3 * kPointerSize)); 3146 __ add(Operand(esp), Immediate(3 * kPointerSize));
3143 __ mov(eax, FACTORY->undefined_value()); 3147 __ mov(eax, isolate()->factory()->undefined_value());
3144 __ jmp(&done); 3148 __ jmp(&done);
3145 3149
3146 __ bind(&slow_case); 3150 __ bind(&slow_case);
3147 __ CallRuntime(Runtime::kSwapElements, 3); 3151 __ CallRuntime(Runtime::kSwapElements, 3);
3148 3152
3149 __ bind(&done); 3153 __ bind(&done);
3150 context()->Plug(eax); 3154 context()->Plug(eax);
3151 } 3155 }
3152 3156
3153 3157
3154 void FullCodeGenerator::EmitGetFromCache(ZoneList<Expression*>* args) { 3158 void FullCodeGenerator::EmitGetFromCache(ZoneList<Expression*>* args) {
3155 ASSERT_EQ(2, args->length()); 3159 ASSERT_EQ(2, args->length());
3156 3160
3157 ASSERT_NE(NULL, args->at(0)->AsLiteral()); 3161 ASSERT_NE(NULL, args->at(0)->AsLiteral());
3158 int cache_id = Smi::cast(*(args->at(0)->AsLiteral()->handle()))->value(); 3162 int cache_id = Smi::cast(*(args->at(0)->AsLiteral()->handle()))->value();
3159 3163
3160 Handle<FixedArray> jsfunction_result_caches( 3164 Handle<FixedArray> jsfunction_result_caches(
3161 Isolate::Current()->global_context()->jsfunction_result_caches()); 3165 isolate()->global_context()->jsfunction_result_caches());
3162 if (jsfunction_result_caches->length() <= cache_id) { 3166 if (jsfunction_result_caches->length() <= cache_id) {
3163 __ Abort("Attempt to use undefined cache."); 3167 __ Abort("Attempt to use undefined cache.");
3164 __ mov(eax, FACTORY->undefined_value()); 3168 __ mov(eax, isolate()->factory()->undefined_value());
3165 context()->Plug(eax); 3169 context()->Plug(eax);
3166 return; 3170 return;
3167 } 3171 }
3168 3172
3169 VisitForAccumulatorValue(args->at(1)); 3173 VisitForAccumulatorValue(args->at(1));
3170 3174
3171 Register key = eax; 3175 Register key = eax;
3172 Register cache = ebx; 3176 Register cache = ebx;
3173 Register tmp = ecx; 3177 Register tmp = ecx;
3174 __ mov(cache, ContextOperand(esi, Context::GLOBAL_INDEX)); 3178 __ mov(cache, ContextOperand(esi, Context::GLOBAL_INDEX));
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
3220 __ j(zero, &fail); 3224 __ j(zero, &fail);
3221 __ mov(tmp, FieldOperand(left, HeapObject::kMapOffset)); 3225 __ mov(tmp, FieldOperand(left, HeapObject::kMapOffset));
3222 __ CmpInstanceType(tmp, JS_REGEXP_TYPE); 3226 __ CmpInstanceType(tmp, JS_REGEXP_TYPE);
3223 __ j(not_equal, &fail); 3227 __ j(not_equal, &fail);
3224 __ cmp(tmp, FieldOperand(right, HeapObject::kMapOffset)); 3228 __ cmp(tmp, FieldOperand(right, HeapObject::kMapOffset));
3225 __ j(not_equal, &fail); 3229 __ j(not_equal, &fail);
3226 __ mov(tmp, FieldOperand(left, JSRegExp::kDataOffset)); 3230 __ mov(tmp, FieldOperand(left, JSRegExp::kDataOffset));
3227 __ cmp(tmp, FieldOperand(right, JSRegExp::kDataOffset)); 3231 __ cmp(tmp, FieldOperand(right, JSRegExp::kDataOffset));
3228 __ j(equal, &ok); 3232 __ j(equal, &ok);
3229 __ bind(&fail); 3233 __ bind(&fail);
3230 __ mov(eax, Immediate(FACTORY->false_value())); 3234 __ mov(eax, Immediate(isolate()->factory()->false_value()));
3231 __ jmp(&done); 3235 __ jmp(&done);
3232 __ bind(&ok); 3236 __ bind(&ok);
3233 __ mov(eax, Immediate(FACTORY->true_value())); 3237 __ mov(eax, Immediate(isolate()->factory()->true_value()));
3234 __ bind(&done); 3238 __ bind(&done);
3235 3239
3236 context()->Plug(eax); 3240 context()->Plug(eax);
3237 } 3241 }
3238 3242
3239 3243
3240 void FullCodeGenerator::EmitHasCachedArrayIndex(ZoneList<Expression*>* args) { 3244 void FullCodeGenerator::EmitHasCachedArrayIndex(ZoneList<Expression*>* args) {
3241 ASSERT(args->length() == 1); 3245 ASSERT(args->length() == 1);
3242 3246
3243 VisitForAccumulatorValue(args->at(0)); 3247 VisitForAccumulatorValue(args->at(0));
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
3320 // Check that the array has fast elements. 3324 // Check that the array has fast elements.
3321 __ test_b(FieldOperand(scratch, Map::kBitField2Offset), 3325 __ test_b(FieldOperand(scratch, Map::kBitField2Offset),
3322 1 << Map::kHasFastElements); 3326 1 << Map::kHasFastElements);
3323 __ j(zero, &bailout); 3327 __ j(zero, &bailout);
3324 3328
3325 // If the array is empty, return the empty string. 3329 // If the array is empty, return the empty string.
3326 __ mov(scratch, FieldOperand(array, JSArray::kLengthOffset)); 3330 __ mov(scratch, FieldOperand(array, JSArray::kLengthOffset));
3327 __ sar(scratch, 1); 3331 __ sar(scratch, 1);
3328 Label non_trivial; 3332 Label non_trivial;
3329 __ j(not_zero, &non_trivial); 3333 __ j(not_zero, &non_trivial);
3330 __ mov(result, FACTORY->empty_string()); 3334 __ mov(result, isolate()->factory()->empty_string());
3331 __ jmp(&done); 3335 __ jmp(&done);
3332 3336
3333 __ bind(&non_trivial); 3337 __ bind(&non_trivial);
3334 __ mov(array_length, scratch); 3338 __ mov(array_length, scratch);
3335 3339
3336 __ mov(scratch, FieldOperand(array, JSArray::kElementsOffset)); 3340 __ mov(scratch, FieldOperand(array, JSArray::kElementsOffset));
3337 __ mov(elements, scratch); 3341 __ mov(elements, scratch);
3338 3342
3339 // End of array's live range. 3343 // End of array's live range.
3340 result_pos = array; 3344 result_pos = array;
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
3444 __ j(not_equal, &bailout); 3448 __ j(not_equal, &bailout);
3445 3449
3446 // Append current to the result. 3450 // Append current to the result.
3447 __ AppendStringToTopOfNewSpace(current_string, current_string_length, 3451 __ AppendStringToTopOfNewSpace(current_string, current_string_length,
3448 result_pos, scratch, scratch_2, result, 3452 result_pos, scratch, scratch_2, result,
3449 padding_chars, &bailout); 3453 padding_chars, &bailout);
3450 __ add(Operand(index), Immediate(1)); 3454 __ add(Operand(index), Immediate(1));
3451 __ jmp(&loop); // End while (index < length). 3455 __ jmp(&loop); // End while (index < length).
3452 3456
3453 __ bind(&bailout); 3457 __ bind(&bailout);
3454 __ mov(result, FACTORY->undefined_value()); 3458 __ mov(result, isolate()->factory()->undefined_value());
3455 __ bind(&done); 3459 __ bind(&done);
3456 __ mov(eax, result); 3460 __ mov(eax, result);
3457 // Drop temp values from the stack, and restore context register. 3461 // Drop temp values from the stack, and restore context register.
3458 __ add(Operand(esp), Immediate(5 * kPointerSize)); 3462 __ add(Operand(esp), Immediate(5 * kPointerSize));
3459 3463
3460 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 3464 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
3461 context()->Plug(eax); 3465 context()->Plug(eax);
3462 } 3466 }
3463 3467
3464 3468
(...skipping 17 matching lines...) Expand all
3482 // Push the arguments ("left-to-right"). 3486 // Push the arguments ("left-to-right").
3483 int arg_count = args->length(); 3487 int arg_count = args->length();
3484 for (int i = 0; i < arg_count; i++) { 3488 for (int i = 0; i < arg_count; i++) {
3485 VisitForStackValue(args->at(i)); 3489 VisitForStackValue(args->at(i));
3486 } 3490 }
3487 3491
3488 if (expr->is_jsruntime()) { 3492 if (expr->is_jsruntime()) {
3489 // Call the JS runtime function via a call IC. 3493 // Call the JS runtime function via a call IC.
3490 __ Set(ecx, Immediate(expr->name())); 3494 __ Set(ecx, Immediate(expr->name()));
3491 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; 3495 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
3492 Handle<Code> ic = ISOLATE->stub_cache()->ComputeCallInitialize(arg_count, 3496 Handle<Code> ic = isolate()->stub_cache()->ComputeCallInitialize(
3493 in_loop); 3497 arg_count, in_loop);
3494 EmitCallIC(ic, RelocInfo::CODE_TARGET); 3498 EmitCallIC(ic, RelocInfo::CODE_TARGET);
3495 // Restore context register. 3499 // Restore context register.
3496 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 3500 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
3497 } else { 3501 } else {
3498 // Call the C runtime function. 3502 // Call the C runtime function.
3499 __ CallRuntime(expr->function(), arg_count); 3503 __ CallRuntime(expr->function(), arg_count);
3500 } 3504 }
3501 context()->Plug(eax); 3505 context()->Plug(eax);
3502 } 3506 }
3503 3507
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
3540 } 3544 }
3541 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); 3545 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
3542 context()->Plug(eax); 3546 context()->Plug(eax);
3543 } 3547 }
3544 break; 3548 break;
3545 } 3549 }
3546 3550
3547 case Token::VOID: { 3551 case Token::VOID: {
3548 Comment cmnt(masm_, "[ UnaryOperation (VOID)"); 3552 Comment cmnt(masm_, "[ UnaryOperation (VOID)");
3549 VisitForEffect(expr->expression()); 3553 VisitForEffect(expr->expression());
3550 context()->Plug(FACTORY->undefined_value()); 3554 context()->Plug(isolate()->factory()->undefined_value());
3551 break; 3555 break;
3552 } 3556 }
3553 3557
3554 case Token::NOT: { 3558 case Token::NOT: {
3555 Comment cmnt(masm_, "[ UnaryOperation (NOT)"); 3559 Comment cmnt(masm_, "[ UnaryOperation (NOT)");
3556 3560
3557 Label materialize_true, materialize_false; 3561 Label materialize_true, materialize_false;
3558 Label* if_true = NULL; 3562 Label* if_true = NULL;
3559 Label* if_false = NULL; 3563 Label* if_false = NULL;
3560 Label* fall_through = NULL; 3564 Label* fall_through = NULL;
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
3776 } 3780 }
3777 } else { 3781 } else {
3778 // Perform the assignment as if via '='. 3782 // Perform the assignment as if via '='.
3779 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 3783 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
3780 Token::ASSIGN); 3784 Token::ASSIGN);
3781 } 3785 }
3782 break; 3786 break;
3783 case NAMED_PROPERTY: { 3787 case NAMED_PROPERTY: {
3784 __ mov(ecx, prop->key()->AsLiteral()->handle()); 3788 __ mov(ecx, prop->key()->AsLiteral()->handle());
3785 __ pop(edx); 3789 __ pop(edx);
3786 Handle<Code> ic(Isolate::Current()->builtins()->builtin( 3790 Handle<Code> ic(isolate()->builtins()->builtin(
3787 Builtins::StoreIC_Initialize)); 3791 Builtins::StoreIC_Initialize));
3788 EmitCallIC(ic, RelocInfo::CODE_TARGET); 3792 EmitCallIC(ic, RelocInfo::CODE_TARGET);
3789 if (expr->is_postfix()) { 3793 if (expr->is_postfix()) {
3790 if (!context()->IsEffect()) { 3794 if (!context()->IsEffect()) {
3791 context()->PlugTOS(); 3795 context()->PlugTOS();
3792 } 3796 }
3793 } else { 3797 } else {
3794 context()->Plug(eax); 3798 context()->Plug(eax);
3795 } 3799 }
3796 break; 3800 break;
3797 } 3801 }
3798 case KEYED_PROPERTY: { 3802 case KEYED_PROPERTY: {
3799 __ pop(ecx); 3803 __ pop(ecx);
3800 __ pop(edx); 3804 __ pop(edx);
3801 Handle<Code> ic(Isolate::Current()->builtins()->builtin( 3805 Handle<Code> ic(isolate()->builtins()->builtin(
3802 Builtins::KeyedStoreIC_Initialize)); 3806 Builtins::KeyedStoreIC_Initialize));
3803 EmitCallIC(ic, RelocInfo::CODE_TARGET); 3807 EmitCallIC(ic, RelocInfo::CODE_TARGET);
3804 if (expr->is_postfix()) { 3808 if (expr->is_postfix()) {
3805 // Result is on the stack 3809 // Result is on the stack
3806 if (!context()->IsEffect()) { 3810 if (!context()->IsEffect()) {
3807 context()->PlugTOS(); 3811 context()->PlugTOS();
3808 } 3812 }
3809 } else { 3813 } else {
3810 context()->Plug(eax); 3814 context()->Plug(eax);
3811 } 3815 }
3812 break; 3816 break;
3813 } 3817 }
3814 } 3818 }
3815 } 3819 }
3816 3820
3817 3821
3818 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { 3822 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) {
3819 VariableProxy* proxy = expr->AsVariableProxy(); 3823 VariableProxy* proxy = expr->AsVariableProxy();
3820 ASSERT(!context()->IsEffect()); 3824 ASSERT(!context()->IsEffect());
3821 ASSERT(!context()->IsTest()); 3825 ASSERT(!context()->IsTest());
3822 3826
3823 if (proxy != NULL && !proxy->var()->is_this() && proxy->var()->is_global()) { 3827 if (proxy != NULL && !proxy->var()->is_this() && proxy->var()->is_global()) {
3824 Comment cmnt(masm_, "Global variable"); 3828 Comment cmnt(masm_, "Global variable");
3825 __ mov(eax, GlobalObjectOperand()); 3829 __ mov(eax, GlobalObjectOperand());
3826 __ mov(ecx, Immediate(proxy->name())); 3830 __ mov(ecx, Immediate(proxy->name()));
3827 Handle<Code> ic(Isolate::Current()->builtins()->builtin( 3831 Handle<Code> ic(isolate()->builtins()->builtin(
3828 Builtins::LoadIC_Initialize)); 3832 Builtins::LoadIC_Initialize));
3829 // Use a regular load, not a contextual load, to avoid a reference 3833 // Use a regular load, not a contextual load, to avoid a reference
3830 // error. 3834 // error.
3831 EmitCallIC(ic, RelocInfo::CODE_TARGET); 3835 EmitCallIC(ic, RelocInfo::CODE_TARGET);
3832 PrepareForBailout(expr, TOS_REG); 3836 PrepareForBailout(expr, TOS_REG);
3833 context()->Plug(eax); 3837 context()->Plug(eax);
3834 } else if (proxy != NULL && 3838 } else if (proxy != NULL &&
3835 proxy->var()->AsSlot() != NULL && 3839 proxy->var()->AsSlot() != NULL &&
3836 proxy->var()->AsSlot()->type() == Slot::LOOKUP) { 3840 proxy->var()->AsSlot()->type() == Slot::LOOKUP) {
3837 Label done, slow; 3841 Label done, slow;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
3871 if (!right_literal_value->IsString()) return false; 3875 if (!right_literal_value->IsString()) return false;
3872 UnaryOperation* left_unary = left->AsUnaryOperation(); 3876 UnaryOperation* left_unary = left->AsUnaryOperation();
3873 if (left_unary == NULL || left_unary->op() != Token::TYPEOF) return false; 3877 if (left_unary == NULL || left_unary->op() != Token::TYPEOF) return false;
3874 Handle<String> check = Handle<String>::cast(right_literal_value); 3878 Handle<String> check = Handle<String>::cast(right_literal_value);
3875 3879
3876 { AccumulatorValueContext context(this); 3880 { AccumulatorValueContext context(this);
3877 VisitForTypeofValue(left_unary->expression()); 3881 VisitForTypeofValue(left_unary->expression());
3878 } 3882 }
3879 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); 3883 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
3880 3884
3881 if (check->Equals(HEAP->number_symbol())) { 3885 if (check->Equals(isolate()->heap()->number_symbol())) {
3882 __ test(eax, Immediate(kSmiTagMask)); 3886 __ test(eax, Immediate(kSmiTagMask));
3883 __ j(zero, if_true); 3887 __ j(zero, if_true);
3884 __ cmp(FieldOperand(eax, HeapObject::kMapOffset), 3888 __ cmp(FieldOperand(eax, HeapObject::kMapOffset),
3885 FACTORY->heap_number_map()); 3889 isolate()->factory()->heap_number_map());
3886 Split(equal, if_true, if_false, fall_through); 3890 Split(equal, if_true, if_false, fall_through);
3887 } else if (check->Equals(HEAP->string_symbol())) { 3891 } else if (check->Equals(isolate()->heap()->string_symbol())) {
3888 __ test(eax, Immediate(kSmiTagMask)); 3892 __ test(eax, Immediate(kSmiTagMask));
3889 __ j(zero, if_false); 3893 __ j(zero, if_false);
3890 // Check for undetectable objects => false. 3894 // Check for undetectable objects => false.
3891 __ mov(edx, FieldOperand(eax, HeapObject::kMapOffset)); 3895 __ mov(edx, FieldOperand(eax, HeapObject::kMapOffset));
3892 __ movzx_b(ecx, FieldOperand(edx, Map::kBitFieldOffset)); 3896 __ movzx_b(ecx, FieldOperand(edx, Map::kBitFieldOffset));
3893 __ test(ecx, Immediate(1 << Map::kIsUndetectable)); 3897 __ test(ecx, Immediate(1 << Map::kIsUndetectable));
3894 __ j(not_zero, if_false); 3898 __ j(not_zero, if_false);
3895 __ CmpInstanceType(edx, FIRST_NONSTRING_TYPE); 3899 __ CmpInstanceType(edx, FIRST_NONSTRING_TYPE);
3896 Split(below, if_true, if_false, fall_through); 3900 Split(below, if_true, if_false, fall_through);
3897 } else if (check->Equals(HEAP->boolean_symbol())) { 3901 } else if (check->Equals(isolate()->heap()->boolean_symbol())) {
3898 __ cmp(eax, FACTORY->true_value()); 3902 __ cmp(eax, isolate()->factory()->true_value());
3899 __ j(equal, if_true); 3903 __ j(equal, if_true);
3900 __ cmp(eax, FACTORY->false_value()); 3904 __ cmp(eax, isolate()->factory()->false_value());
3901 Split(equal, if_true, if_false, fall_through); 3905 Split(equal, if_true, if_false, fall_through);
3902 } else if (check->Equals(HEAP->undefined_symbol())) { 3906 } else if (check->Equals(isolate()->heap()->undefined_symbol())) {
3903 __ cmp(eax, FACTORY->undefined_value()); 3907 __ cmp(eax, isolate()->factory()->undefined_value());
3904 __ j(equal, if_true); 3908 __ j(equal, if_true);
3905 __ test(eax, Immediate(kSmiTagMask)); 3909 __ test(eax, Immediate(kSmiTagMask));
3906 __ j(zero, if_false); 3910 __ j(zero, if_false);
3907 // Check for undetectable objects => true. 3911 // Check for undetectable objects => true.
3908 __ mov(edx, FieldOperand(eax, HeapObject::kMapOffset)); 3912 __ mov(edx, FieldOperand(eax, HeapObject::kMapOffset));
3909 __ movzx_b(ecx, FieldOperand(edx, Map::kBitFieldOffset)); 3913 __ movzx_b(ecx, FieldOperand(edx, Map::kBitFieldOffset));
3910 __ test(ecx, Immediate(1 << Map::kIsUndetectable)); 3914 __ test(ecx, Immediate(1 << Map::kIsUndetectable));
3911 Split(not_zero, if_true, if_false, fall_through); 3915 Split(not_zero, if_true, if_false, fall_through);
3912 } else if (check->Equals(HEAP->function_symbol())) { 3916 } else if (check->Equals(isolate()->heap()->function_symbol())) {
3913 __ test(eax, Immediate(kSmiTagMask)); 3917 __ test(eax, Immediate(kSmiTagMask));
3914 __ j(zero, if_false); 3918 __ j(zero, if_false);
3915 __ CmpObjectType(eax, JS_FUNCTION_TYPE, edx); 3919 __ CmpObjectType(eax, JS_FUNCTION_TYPE, edx);
3916 __ j(equal, if_true); 3920 __ j(equal, if_true);
3917 // Regular expressions => 'function' (they are callable). 3921 // Regular expressions => 'function' (they are callable).
3918 __ CmpInstanceType(edx, JS_REGEXP_TYPE); 3922 __ CmpInstanceType(edx, JS_REGEXP_TYPE);
3919 Split(equal, if_true, if_false, fall_through); 3923 Split(equal, if_true, if_false, fall_through);
3920 } else if (check->Equals(HEAP->object_symbol())) { 3924 } else if (check->Equals(isolate()->heap()->object_symbol())) {
3921 __ test(eax, Immediate(kSmiTagMask)); 3925 __ test(eax, Immediate(kSmiTagMask));
3922 __ j(zero, if_false); 3926 __ j(zero, if_false);
3923 __ cmp(eax, FACTORY->null_value()); 3927 __ cmp(eax, isolate()->factory()->null_value());
3924 __ j(equal, if_true); 3928 __ j(equal, if_true);
3925 // Regular expressions => 'function', not 'object'. 3929 // Regular expressions => 'function', not 'object'.
3926 __ CmpObjectType(eax, JS_REGEXP_TYPE, edx); 3930 __ CmpObjectType(eax, JS_REGEXP_TYPE, edx);
3927 __ j(equal, if_false); 3931 __ j(equal, if_false);
3928 // Check for undetectable objects => false. 3932 // Check for undetectable objects => false.
3929 __ movzx_b(ecx, FieldOperand(edx, Map::kBitFieldOffset)); 3933 __ movzx_b(ecx, FieldOperand(edx, Map::kBitFieldOffset));
3930 __ test(ecx, Immediate(1 << Map::kIsUndetectable)); 3934 __ test(ecx, Immediate(1 << Map::kIsUndetectable));
3931 __ j(not_zero, if_false); 3935 __ j(not_zero, if_false);
3932 // Check for JS objects => true. 3936 // Check for JS objects => true.
3933 __ movzx_b(ecx, FieldOperand(edx, Map::kInstanceTypeOffset)); 3937 __ movzx_b(ecx, FieldOperand(edx, Map::kInstanceTypeOffset));
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
3966 context()->Plug(if_true, if_false); 3970 context()->Plug(if_true, if_false);
3967 return; 3971 return;
3968 } 3972 }
3969 3973
3970 VisitForStackValue(expr->left()); 3974 VisitForStackValue(expr->left());
3971 switch (expr->op()) { 3975 switch (expr->op()) {
3972 case Token::IN: 3976 case Token::IN:
3973 VisitForStackValue(expr->right()); 3977 VisitForStackValue(expr->right());
3974 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION); 3978 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION);
3975 PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL); 3979 PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL);
3976 __ cmp(eax, FACTORY->true_value()); 3980 __ cmp(eax, isolate()->factory()->true_value());
3977 Split(equal, if_true, if_false, fall_through); 3981 Split(equal, if_true, if_false, fall_through);
3978 break; 3982 break;
3979 3983
3980 case Token::INSTANCEOF: { 3984 case Token::INSTANCEOF: {
3981 VisitForStackValue(expr->right()); 3985 VisitForStackValue(expr->right());
3982 InstanceofStub stub; 3986 InstanceofStub stub;
3983 __ CallStub(&stub); 3987 __ CallStub(&stub);
3984 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); 3988 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
3985 __ test(eax, Operand(eax)); 3989 __ test(eax, Operand(eax));
3986 // The stub returns 0 for true. 3990 // The stub returns 0 for true.
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
4058 Label materialize_true, materialize_false; 4062 Label materialize_true, materialize_false;
4059 Label* if_true = NULL; 4063 Label* if_true = NULL;
4060 Label* if_false = NULL; 4064 Label* if_false = NULL;
4061 Label* fall_through = NULL; 4065 Label* fall_through = NULL;
4062 context()->PrepareTest(&materialize_true, &materialize_false, 4066 context()->PrepareTest(&materialize_true, &materialize_false,
4063 &if_true, &if_false, &fall_through); 4067 &if_true, &if_false, &fall_through);
4064 4068
4065 VisitForAccumulatorValue(expr->expression()); 4069 VisitForAccumulatorValue(expr->expression());
4066 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); 4070 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
4067 4071
4068 __ cmp(eax, FACTORY->null_value()); 4072 __ cmp(eax, isolate()->factory()->null_value());
4069 if (expr->is_strict()) { 4073 if (expr->is_strict()) {
4070 Split(equal, if_true, if_false, fall_through); 4074 Split(equal, if_true, if_false, fall_through);
4071 } else { 4075 } else {
4072 __ j(equal, if_true); 4076 __ j(equal, if_true);
4073 __ cmp(eax, FACTORY->undefined_value()); 4077 __ cmp(eax, isolate()->factory()->undefined_value());
4074 __ j(equal, if_true); 4078 __ j(equal, if_true);
4075 __ test(eax, Immediate(kSmiTagMask)); 4079 __ test(eax, Immediate(kSmiTagMask));
4076 __ j(zero, if_false); 4080 __ j(zero, if_false);
4077 // It can be an undetectable object. 4081 // It can be an undetectable object.
4078 __ mov(edx, FieldOperand(eax, HeapObject::kMapOffset)); 4082 __ mov(edx, FieldOperand(eax, HeapObject::kMapOffset));
4079 __ movzx_b(edx, FieldOperand(edx, Map::kBitFieldOffset)); 4083 __ movzx_b(edx, FieldOperand(edx, Map::kBitFieldOffset));
4080 __ test(edx, Immediate(1 << Map::kIsUndetectable)); 4084 __ test(edx, Immediate(1 << Map::kIsUndetectable));
4081 Split(not_zero, if_true, if_false, fall_through); 4085 Split(not_zero, if_true, if_false, fall_through);
4082 } 4086 }
4083 context()->Plug(if_true, if_false); 4087 context()->Plug(if_true, if_false);
(...skipping 14 matching lines...) Expand all
4098 Register FullCodeGenerator::context_register() { 4102 Register FullCodeGenerator::context_register() {
4099 return esi; 4103 return esi;
4100 } 4104 }
4101 4105
4102 4106
4103 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, RelocInfo::Mode mode) { 4107 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, RelocInfo::Mode mode) {
4104 ASSERT(mode == RelocInfo::CODE_TARGET || 4108 ASSERT(mode == RelocInfo::CODE_TARGET ||
4105 mode == RelocInfo::CODE_TARGET_CONTEXT); 4109 mode == RelocInfo::CODE_TARGET_CONTEXT);
4106 switch (ic->kind()) { 4110 switch (ic->kind()) {
4107 case Code::LOAD_IC: 4111 case Code::LOAD_IC:
4108 __ IncrementCounter(COUNTERS->named_load_full(), 1); 4112 __ IncrementCounter(isolate()->counters()->named_load_full(), 1);
4109 break; 4113 break;
4110 case Code::KEYED_LOAD_IC: 4114 case Code::KEYED_LOAD_IC:
4111 __ IncrementCounter(COUNTERS->keyed_load_full(), 1); 4115 __ IncrementCounter(isolate()->counters()->keyed_load_full(), 1);
4112 break; 4116 break;
4113 case Code::STORE_IC: 4117 case Code::STORE_IC:
4114 __ IncrementCounter(COUNTERS->named_store_full(), 1); 4118 __ IncrementCounter(isolate()->counters()->named_store_full(), 1);
4115 break; 4119 break;
4116 case Code::KEYED_STORE_IC: 4120 case Code::KEYED_STORE_IC:
4117 __ IncrementCounter(COUNTERS->keyed_store_full(), 1); 4121 __ IncrementCounter(isolate()->counters()->keyed_store_full(), 1);
4118 default: 4122 default:
4119 break; 4123 break;
4120 } 4124 }
4121 4125
4122 __ call(ic, mode); 4126 __ call(ic, mode);
4123 4127
4124 // Crankshaft doesn't need patching of inlined loads and stores. 4128 // Crankshaft doesn't need patching of inlined loads and stores.
4125 // When compiling the snapshot we need to produce code that works 4129 // When compiling the snapshot we need to produce code that works
4126 // with and without Crankshaft. 4130 // with and without Crankshaft.
4127 if (V8::UseCrankshaft() && !Serializer::enabled()) { 4131 if (V8::UseCrankshaft() && !Serializer::enabled()) {
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
4185 // And return. 4189 // And return.
4186 __ ret(0); 4190 __ ret(0);
4187 } 4191 }
4188 4192
4189 4193
4190 #undef __ 4194 #undef __
4191 4195
4192 } } // namespace v8::internal 4196 } } // namespace v8::internal
4193 4197
4194 #endif // V8_TARGET_ARCH_IA32 4198 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/full-codegen.cc ('k') | src/parser.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698