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

Side by Side Diff: src/mips/stub-cache-mips.cc

Issue 8400087: MIPS: Handlify CompileConstructStub and the remaining CallStubCompiler functions. (Closed)
Patch Set: Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/mips/macro-assembler-mips.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
144 &done, 144 &done,
145 receiver, 145 receiver,
146 properties, 146 properties,
147 name, 147 name,
148 scratch1); 148 scratch1);
149 __ bind(&done); 149 __ bind(&done);
150 __ DecrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); 150 __ DecrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1);
151 } 151 }
152 152
153 153
154 // TODO(kmillikin): Eliminate this function when the stub cache is fully
155 // handlified.
156 MUST_USE_RESULT static MaybeObject* TryGenerateDictionaryNegativeLookup(
157 MacroAssembler* masm,
158 Label* miss_label,
159 Register receiver,
160 String* name,
161 Register scratch0,
162 Register scratch1) {
163 ASSERT(name->IsSymbol());
164 Counters* counters = masm->isolate()->counters();
165 __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1);
166 __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1);
167
168 Label done;
169
170 const int kInterceptorOrAccessCheckNeededMask =
171 (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded);
172
173 // Bail out if the receiver has a named interceptor or requires access checks.
174 Register map = scratch1;
175 __ lw(map, FieldMemOperand(receiver, HeapObject::kMapOffset));
176 __ lbu(scratch0, FieldMemOperand(map, Map::kBitFieldOffset));
177 __ And(at, scratch0, Operand(kInterceptorOrAccessCheckNeededMask));
178 __ Branch(miss_label, ne, at, Operand(zero_reg));
179
180
181 // Check that receiver is a JSObject.
182 __ lbu(scratch0, FieldMemOperand(map, Map::kInstanceTypeOffset));
183 __ Branch(miss_label, lt, scratch0, Operand(FIRST_SPEC_OBJECT_TYPE));
184
185 // Load properties array.
186 Register properties = scratch0;
187 __ lw(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset));
188 // Check that the properties array is a dictionary.
189 __ lw(map, FieldMemOperand(properties, HeapObject::kMapOffset));
190 Register tmp = properties;
191 __ LoadRoot(tmp, Heap::kHashTableMapRootIndex);
192 __ Branch(miss_label, ne, map, Operand(tmp));
193
194 // Restore the temporarily used register.
195 __ lw(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset));
196
197 MaybeObject* result = StringDictionaryLookupStub::TryGenerateNegativeLookup(
198 masm,
199 miss_label,
200 &done,
201 receiver,
202 properties,
203 name,
204 scratch1);
205 if (result->IsFailure()) return result;
206
207 __ bind(&done);
208 __ DecrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1);
209
210 return result;
211 }
212
213
214 void StubCache::GenerateProbe(MacroAssembler* masm, 154 void StubCache::GenerateProbe(MacroAssembler* masm,
215 Code::Flags flags, 155 Code::Flags flags,
216 Register receiver, 156 Register receiver,
217 Register name, 157 Register name,
218 Register scratch, 158 Register scratch,
219 Register extra, 159 Register extra,
220 Register extra2) { 160 Register extra2) {
221 Isolate* isolate = masm->isolate(); 161 Isolate* isolate = masm->isolate();
222 Label miss; 162 Label miss;
223 163
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
287 __ lw(prototype, MemOperand(prototype, Context::SlotOffset(index))); 227 __ lw(prototype, MemOperand(prototype, Context::SlotOffset(index)));
288 // Load the initial map. The global functions all have initial maps. 228 // Load the initial map. The global functions all have initial maps.
289 __ lw(prototype, 229 __ lw(prototype,
290 FieldMemOperand(prototype, JSFunction::kPrototypeOrInitialMapOffset)); 230 FieldMemOperand(prototype, JSFunction::kPrototypeOrInitialMapOffset));
291 // Load the prototype from the initial map. 231 // Load the prototype from the initial map.
292 __ lw(prototype, FieldMemOperand(prototype, Map::kPrototypeOffset)); 232 __ lw(prototype, FieldMemOperand(prototype, Map::kPrototypeOffset));
293 } 233 }
294 234
295 235
296 void StubCompiler::GenerateDirectLoadGlobalFunctionPrototype( 236 void StubCompiler::GenerateDirectLoadGlobalFunctionPrototype(
297 MacroAssembler* masm, int index, Register prototype, Label* miss) { 237 MacroAssembler* masm,
238 int index,
239 Register prototype,
240 Label* miss) {
298 Isolate* isolate = masm->isolate(); 241 Isolate* isolate = masm->isolate();
299 // Check we're still in the same context. 242 // Check we're still in the same context.
300 __ lw(prototype, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX))); 243 __ lw(prototype, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX)));
301 ASSERT(!prototype.is(at)); 244 ASSERT(!prototype.is(at));
302 __ li(at, isolate->global()); 245 __ li(at, isolate->global());
303 __ Branch(miss, ne, prototype, Operand(at)); 246 __ Branch(miss, ne, prototype, Operand(at));
304 // Get the global function with the given index. 247 // Get the global function with the given index.
305 JSFunction* function = 248 Handle<JSFunction> function(
306 JSFunction::cast(isolate->global_context()->get(index)); 249 JSFunction::cast(isolate->global_context()->get(index)));
307 // Load its initial map. The global functions all have initial maps. 250 // Load its initial map. The global functions all have initial maps.
308 __ li(prototype, Handle<Map>(function->initial_map())); 251 __ li(prototype, Handle<Map>(function->initial_map()));
309 // Load the prototype from the initial map. 252 // Load the prototype from the initial map.
310 __ lw(prototype, FieldMemOperand(prototype, Map::kPrototypeOffset)); 253 __ lw(prototype, FieldMemOperand(prototype, Map::kPrototypeOffset));
311 } 254 }
312 255
313 256
314 // Load a fast property out of a holder object (src). In-object properties 257 // Load a fast property out of a holder object (src). In-object properties
315 // are loaded directly otherwise the property is loaded from the properties 258 // are loaded directly otherwise the property is loaded from the properties
316 // fixed array. 259 // fixed array.
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after
558 ? CALL_AS_FUNCTION 501 ? CALL_AS_FUNCTION
559 : CALL_AS_METHOD; 502 : CALL_AS_METHOD;
560 __ InvokeFunction(a1, arguments, JUMP_FUNCTION, NullCallWrapper(), call_kind); 503 __ InvokeFunction(a1, arguments, JUMP_FUNCTION, NullCallWrapper(), call_kind);
561 } 504 }
562 505
563 506
564 static void PushInterceptorArguments(MacroAssembler* masm, 507 static void PushInterceptorArguments(MacroAssembler* masm,
565 Register receiver, 508 Register receiver,
566 Register holder, 509 Register holder,
567 Register name, 510 Register name,
568 JSObject* holder_obj) { 511 Handle<JSObject> holder_obj) {
569 __ push(name); 512 __ push(name);
570 InterceptorInfo* interceptor = holder_obj->GetNamedInterceptor(); 513 Handle<InterceptorInfo> interceptor(holder_obj->GetNamedInterceptor());
571 ASSERT(!masm->isolate()->heap()->InNewSpace(interceptor)); 514 ASSERT(!masm->isolate()->heap()->InNewSpace(*interceptor));
572 Register scratch = name; 515 Register scratch = name;
573 __ li(scratch, Operand(Handle<Object>(interceptor))); 516 __ li(scratch, Operand(interceptor));
574 __ Push(scratch, receiver, holder); 517 __ Push(scratch, receiver, holder);
575 __ lw(scratch, FieldMemOperand(scratch, InterceptorInfo::kDataOffset)); 518 __ lw(scratch, FieldMemOperand(scratch, InterceptorInfo::kDataOffset));
576 __ push(scratch); 519 __ push(scratch);
577 } 520 }
578 521
579 522
580 static void CompileCallLoadPropertyWithInterceptor(MacroAssembler* masm, 523 static void CompileCallLoadPropertyWithInterceptor(
581 Register receiver, 524 MacroAssembler* masm,
582 Register holder, 525 Register receiver,
583 Register name, 526 Register holder,
584 JSObject* holder_obj) { 527 Register name,
528 Handle<JSObject> holder_obj) {
585 PushInterceptorArguments(masm, receiver, holder, name, holder_obj); 529 PushInterceptorArguments(masm, receiver, holder, name, holder_obj);
586 530
587 ExternalReference ref = 531 ExternalReference ref =
588 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorOnly), 532 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorOnly),
589 masm->isolate()); 533 masm->isolate());
590 __ li(a0, Operand(5)); 534 __ li(a0, Operand(5));
591 __ li(a1, Operand(ref)); 535 __ li(a1, Operand(ref));
592 536
593 CEntryStub stub(1); 537 CEntryStub stub(1);
594 __ CallStub(&stub); 538 __ CallStub(&stub);
(...skipping 15 matching lines...) Expand all
610 } 554 }
611 } 555 }
612 556
613 557
614 // Undoes the effects of ReserveSpaceForFastApiCall. 558 // Undoes the effects of ReserveSpaceForFastApiCall.
615 static void FreeSpaceForFastApiCall(MacroAssembler* masm) { 559 static void FreeSpaceForFastApiCall(MacroAssembler* masm) {
616 __ Drop(kFastApiCallArguments); 560 __ Drop(kFastApiCallArguments);
617 } 561 }
618 562
619 563
620 static MaybeObject* GenerateFastApiDirectCall( 564 static void GenerateFastApiDirectCall(MacroAssembler* masm,
621 MacroAssembler* masm, 565 const CallOptimization& optimization,
622 const CallOptimization& optimization, 566 int argc) {
623 int argc) {
624 // ----------- S t a t e ------------- 567 // ----------- S t a t e -------------
625 // -- sp[0] : holder (set by CheckPrototypes) 568 // -- sp[0] : holder (set by CheckPrototypes)
626 // -- sp[4] : callee js function 569 // -- sp[4] : callee js function
627 // -- sp[8] : call data 570 // -- sp[8] : call data
628 // -- sp[12] : last js argument 571 // -- sp[12] : last js argument
629 // -- ... 572 // -- ...
630 // -- sp[(argc + 3) * 4] : first js argument 573 // -- sp[(argc + 3) * 4] : first js argument
631 // -- sp[(argc + 4) * 4] : receiver 574 // -- sp[(argc + 4) * 4] : receiver
632 // ----------------------------------- 575 // -----------------------------------
633 // Get the function and setup the context. 576 // Get the function and setup the context.
634 JSFunction* function = optimization.constant_function(); 577 Handle<JSFunction> function = optimization.constant_function();
635 __ li(t1, Operand(Handle<JSFunction>(function))); 578 __ li(t1, Operand(function));
636 __ lw(cp, FieldMemOperand(t1, JSFunction::kContextOffset)); 579 __ lw(cp, FieldMemOperand(t1, JSFunction::kContextOffset));
637 580
638 // Pass the additional arguments FastHandleApiCall expects. 581 // Pass the additional arguments FastHandleApiCall expects.
639 Object* call_data = optimization.api_call_info()->data(); 582 Handle<CallHandlerInfo> api_call_info = optimization.api_call_info();
640 Handle<CallHandlerInfo> api_call_info_handle(optimization.api_call_info()); 583 Handle<Object> call_data(api_call_info->data());
641 if (masm->isolate()->heap()->InNewSpace(call_data)) { 584 if (masm->isolate()->heap()->InNewSpace(*call_data)) {
642 __ li(a0, api_call_info_handle); 585 __ li(a0, api_call_info);
643 __ lw(t2, FieldMemOperand(a0, CallHandlerInfo::kDataOffset)); 586 __ lw(t2, FieldMemOperand(a0, CallHandlerInfo::kDataOffset));
644 } else { 587 } else {
645 __ li(t2, Operand(Handle<Object>(call_data))); 588 __ li(t2, call_data);
646 } 589 }
647 590
648 // Store js function and call data. 591 // Store js function and call data.
649 __ sw(t1, MemOperand(sp, 1 * kPointerSize)); 592 __ sw(t1, MemOperand(sp, 1 * kPointerSize));
650 __ sw(t2, MemOperand(sp, 2 * kPointerSize)); 593 __ sw(t2, MemOperand(sp, 2 * kPointerSize));
651 594
652 // a2 points to call data as expected by Arguments 595 // a2 points to call data as expected by Arguments
653 // (refer to layout above). 596 // (refer to layout above).
654 __ Addu(a2, sp, Operand(2 * kPointerSize)); 597 __ Addu(a2, sp, Operand(2 * kPointerSize));
655 598
656 Object* callback = optimization.api_call_info()->callback();
657 Address api_function_address = v8::ToCData<Address>(callback);
658 ApiFunction fun(api_function_address);
659
660 const int kApiStackSpace = 4; 599 const int kApiStackSpace = 4;
661 600
662 FrameScope frame_scope(masm, StackFrame::MANUAL); 601 FrameScope frame_scope(masm, StackFrame::MANUAL);
663 __ EnterExitFrame(false, kApiStackSpace); 602 __ EnterExitFrame(false, kApiStackSpace);
664 603
665 // NOTE: the O32 abi requires a0 to hold a special pointer when returning a 604 // NOTE: the O32 abi requires a0 to hold a special pointer when returning a
666 // struct from the function (which is currently the case). This means we pass 605 // struct from the function (which is currently the case). This means we pass
667 // the first argument in a1 instead of a0. TryCallApiFunctionAndReturn 606 // the first argument in a1 instead of a0. TryCallApiFunctionAndReturn
668 // will handle setting up a0. 607 // will handle setting up a0.
669 608
670 // a1 = v8::Arguments& 609 // a1 = v8::Arguments&
671 // Arguments is built at sp + 1 (sp is a reserved spot for ra). 610 // Arguments is built at sp + 1 (sp is a reserved spot for ra).
672 __ Addu(a1, sp, kPointerSize); 611 __ Addu(a1, sp, kPointerSize);
673 612
674 // v8::Arguments::implicit_args = data 613 // v8::Arguments::implicit_args = data
675 __ sw(a2, MemOperand(a1, 0 * kPointerSize)); 614 __ sw(a2, MemOperand(a1, 0 * kPointerSize));
676 // v8::Arguments::values = last argument 615 // v8::Arguments::values = last argument
677 __ Addu(t0, a2, Operand(argc * kPointerSize)); 616 __ Addu(t0, a2, Operand(argc * kPointerSize));
678 __ sw(t0, MemOperand(a1, 1 * kPointerSize)); 617 __ sw(t0, MemOperand(a1, 1 * kPointerSize));
679 // v8::Arguments::length_ = argc 618 // v8::Arguments::length_ = argc
680 __ li(t0, Operand(argc)); 619 __ li(t0, Operand(argc));
681 __ sw(t0, MemOperand(a1, 2 * kPointerSize)); 620 __ sw(t0, MemOperand(a1, 2 * kPointerSize));
682 // v8::Arguments::is_construct_call = 0 621 // v8::Arguments::is_construct_call = 0
683 __ sw(zero_reg, MemOperand(a1, 3 * kPointerSize)); 622 __ sw(zero_reg, MemOperand(a1, 3 * kPointerSize));
684 623
685 // Emitting a stub call may try to allocate (if the code is not
686 // already generated). Do not allow the assembler to perform a
687 // garbage collection but instead return the allocation failure
688 // object.
689 const int kStackUnwindSpace = argc + kFastApiCallArguments + 1; 624 const int kStackUnwindSpace = argc + kFastApiCallArguments + 1;
625 Address function_address = v8::ToCData<Address>(api_call_info->callback());
626 ApiFunction fun(function_address);
690 ExternalReference ref = 627 ExternalReference ref =
691 ExternalReference(&fun, 628 ExternalReference(&fun,
692 ExternalReference::DIRECT_API_CALL, 629 ExternalReference::DIRECT_API_CALL,
693 masm->isolate()); 630 masm->isolate());
694 AllowExternalCallThatCantCauseGC scope(masm); 631 AllowExternalCallThatCantCauseGC scope(masm);
695 return masm->TryCallApiFunctionAndReturn(ref, kStackUnwindSpace); 632 __ CallApiFunctionAndReturn(ref, kStackUnwindSpace);
696 } 633 }
697 634
698 class CallInterceptorCompiler BASE_EMBEDDED { 635 class CallInterceptorCompiler BASE_EMBEDDED {
699 public: 636 public:
700 CallInterceptorCompiler(StubCompiler* stub_compiler, 637 CallInterceptorCompiler(StubCompiler* stub_compiler,
701 const ParameterCount& arguments, 638 const ParameterCount& arguments,
702 Register name, 639 Register name,
703 Code::ExtraICState extra_ic_state) 640 Code::ExtraICState extra_ic_state)
704 : stub_compiler_(stub_compiler), 641 : stub_compiler_(stub_compiler),
705 arguments_(arguments), 642 arguments_(arguments),
706 name_(name), 643 name_(name),
707 extra_ic_state_(extra_ic_state) {} 644 extra_ic_state_(extra_ic_state) {}
708 645
709 MaybeObject* Compile(MacroAssembler* masm, 646 void Compile(MacroAssembler* masm,
710 JSObject* object, 647 Handle<JSObject> object,
711 JSObject* holder, 648 Handle<JSObject> holder,
712 String* name, 649 Handle<String> name,
713 LookupResult* lookup, 650 LookupResult* lookup,
714 Register receiver, 651 Register receiver,
715 Register scratch1, 652 Register scratch1,
716 Register scratch2, 653 Register scratch2,
717 Register scratch3, 654 Register scratch3,
718 Label* miss) { 655 Label* miss) {
719 ASSERT(holder->HasNamedInterceptor()); 656 ASSERT(holder->HasNamedInterceptor());
720 ASSERT(!holder->GetNamedInterceptor()->getter()->IsUndefined()); 657 ASSERT(!holder->GetNamedInterceptor()->getter()->IsUndefined());
721 658
722 // Check that the receiver isn't a smi. 659 // Check that the receiver isn't a smi.
723 __ JumpIfSmi(receiver, miss); 660 __ JumpIfSmi(receiver, miss);
724
725 CallOptimization optimization(lookup); 661 CallOptimization optimization(lookup);
726
727 if (optimization.is_constant_call()) { 662 if (optimization.is_constant_call()) {
728 return CompileCacheable(masm, 663 CompileCacheable(masm, object, receiver, scratch1, scratch2, scratch3,
729 object, 664 holder, lookup, name, optimization, miss);
730 receiver,
731 scratch1,
732 scratch2,
733 scratch3,
734 holder,
735 lookup,
736 name,
737 optimization,
738 miss);
739 } else { 665 } else {
740 CompileRegular(masm, 666 CompileRegular(masm, object, receiver, scratch1, scratch2, scratch3,
741 object, 667 name, holder, miss);
742 receiver,
743 scratch1,
744 scratch2,
745 scratch3,
746 name,
747 holder,
748 miss);
749 return masm->isolate()->heap()->undefined_value();
750 } 668 }
751 } 669 }
752 670
753 private: 671 private:
754 MaybeObject* CompileCacheable(MacroAssembler* masm, 672 void CompileCacheable(MacroAssembler* masm,
755 JSObject* object, 673 Handle<JSObject> object,
756 Register receiver, 674 Register receiver,
757 Register scratch1, 675 Register scratch1,
758 Register scratch2, 676 Register scratch2,
759 Register scratch3, 677 Register scratch3,
760 JSObject* interceptor_holder, 678 Handle<JSObject> interceptor_holder,
761 LookupResult* lookup, 679 LookupResult* lookup,
762 String* name, 680 Handle<String> name,
763 const CallOptimization& optimization, 681 const CallOptimization& optimization,
764 Label* miss_label) { 682 Label* miss_label) {
765 ASSERT(optimization.is_constant_call()); 683 ASSERT(optimization.is_constant_call());
766 ASSERT(!lookup->holder()->IsGlobalObject()); 684 ASSERT(!lookup->holder()->IsGlobalObject());
767
768 Counters* counters = masm->isolate()->counters(); 685 Counters* counters = masm->isolate()->counters();
769
770 int depth1 = kInvalidProtoDepth; 686 int depth1 = kInvalidProtoDepth;
771 int depth2 = kInvalidProtoDepth; 687 int depth2 = kInvalidProtoDepth;
772 bool can_do_fast_api_call = false; 688 bool can_do_fast_api_call = false;
773 if (optimization.is_simple_api_call() && 689 if (optimization.is_simple_api_call() &&
774 !lookup->holder()->IsGlobalObject()) { 690 !lookup->holder()->IsGlobalObject()) {
775 depth1 = 691 depth1 = optimization.GetPrototypeDepthOfExpectedType(
776 optimization.GetPrototypeDepthOfExpectedType(object, 692 object, interceptor_holder);
777 interceptor_holder);
778 if (depth1 == kInvalidProtoDepth) { 693 if (depth1 == kInvalidProtoDepth) {
779 depth2 = 694 depth2 = optimization.GetPrototypeDepthOfExpectedType(
780 optimization.GetPrototypeDepthOfExpectedType(interceptor_holder, 695 interceptor_holder, Handle<JSObject>(lookup->holder()));
781 lookup->holder());
782 } 696 }
783 can_do_fast_api_call = (depth1 != kInvalidProtoDepth) || 697 can_do_fast_api_call =
784 (depth2 != kInvalidProtoDepth); 698 depth1 != kInvalidProtoDepth || depth2 != kInvalidProtoDepth;
785 } 699 }
786 700
787 __ IncrementCounter(counters->call_const_interceptor(), 1, 701 __ IncrementCounter(counters->call_const_interceptor(), 1,
788 scratch1, scratch2); 702 scratch1, scratch2);
789 703
790 if (can_do_fast_api_call) { 704 if (can_do_fast_api_call) {
791 __ IncrementCounter(counters->call_const_interceptor_fast_api(), 1, 705 __ IncrementCounter(counters->call_const_interceptor_fast_api(), 1,
792 scratch1, scratch2); 706 scratch1, scratch2);
793 ReserveSpaceForFastApiCall(masm, scratch1); 707 ReserveSpaceForFastApiCall(masm, scratch1);
794 } 708 }
795 709
796 // Check that the maps from receiver to interceptor's holder 710 // Check that the maps from receiver to interceptor's holder
797 // haven't changed and thus we can invoke interceptor. 711 // haven't changed and thus we can invoke interceptor.
798 Label miss_cleanup; 712 Label miss_cleanup;
799 Label* miss = can_do_fast_api_call ? &miss_cleanup : miss_label; 713 Label* miss = can_do_fast_api_call ? &miss_cleanup : miss_label;
800 Register holder = 714 Register holder =
801 stub_compiler_->CheckPrototypes(object, receiver, 715 stub_compiler_->CheckPrototypes(object, receiver, interceptor_holder,
802 interceptor_holder, scratch1, 716 scratch1, scratch2, scratch3,
803 scratch2, scratch3, name, depth1, miss); 717 name, depth1, miss);
804 718
805 // Invoke an interceptor and if it provides a value, 719 // Invoke an interceptor and if it provides a value,
806 // branch to |regular_invoke|. 720 // branch to |regular_invoke|.
807 Label regular_invoke; 721 Label regular_invoke;
808 LoadWithInterceptor(masm, receiver, holder, interceptor_holder, scratch2, 722 LoadWithInterceptor(masm, receiver, holder, interceptor_holder, scratch2,
809 &regular_invoke); 723 &regular_invoke);
810 724
811 // Interceptor returned nothing for this property. Try to use cached 725 // Interceptor returned nothing for this property. Try to use cached
812 // constant function. 726 // constant function.
813 727
814 // Check that the maps from interceptor's holder to constant function's 728 // Check that the maps from interceptor's holder to constant function's
815 // holder haven't changed and thus we can use cached constant function. 729 // holder haven't changed and thus we can use cached constant function.
816 if (interceptor_holder != lookup->holder()) { 730 if (*interceptor_holder != lookup->holder()) {
817 stub_compiler_->CheckPrototypes(interceptor_holder, receiver, 731 stub_compiler_->CheckPrototypes(interceptor_holder, receiver,
818 lookup->holder(), scratch1, 732 Handle<JSObject>(lookup->holder()),
819 scratch2, scratch3, name, depth2, miss); 733 scratch1, scratch2, scratch3,
734 name, depth2, miss);
820 } else { 735 } else {
821 // CheckPrototypes has a side effect of fetching a 'holder' 736 // CheckPrototypes has a side effect of fetching a 'holder'
822 // for API (object which is instanceof for the signature). It's 737 // for API (object which is instanceof for the signature). It's
823 // safe to omit it here, as if present, it should be fetched 738 // safe to omit it here, as if present, it should be fetched
824 // by the previous CheckPrototypes. 739 // by the previous CheckPrototypes.
825 ASSERT(depth2 == kInvalidProtoDepth); 740 ASSERT(depth2 == kInvalidProtoDepth);
826 } 741 }
827 742
828 // Invoke function. 743 // Invoke function.
829 if (can_do_fast_api_call) { 744 if (can_do_fast_api_call) {
830 MaybeObject* result = GenerateFastApiDirectCall(masm, 745 GenerateFastApiDirectCall(masm, optimization, arguments_.immediate());
831 optimization,
832 arguments_.immediate());
833 if (result->IsFailure()) return result;
834 } else { 746 } else {
835 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_) 747 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_)
836 ? CALL_AS_FUNCTION 748 ? CALL_AS_FUNCTION
837 : CALL_AS_METHOD; 749 : CALL_AS_METHOD;
838 __ InvokeFunction(optimization.constant_function(), arguments_, 750 __ InvokeFunction(optimization.constant_function(), arguments_,
839 JUMP_FUNCTION, call_kind); 751 JUMP_FUNCTION, call_kind);
840 } 752 }
841 753
842 // Deferred code for fast API call case---clean preallocated space. 754 // Deferred code for fast API call case---clean preallocated space.
843 if (can_do_fast_api_call) { 755 if (can_do_fast_api_call) {
844 __ bind(&miss_cleanup); 756 __ bind(&miss_cleanup);
845 FreeSpaceForFastApiCall(masm); 757 FreeSpaceForFastApiCall(masm);
846 __ Branch(miss_label); 758 __ Branch(miss_label);
847 } 759 }
848 760
849 // Invoke a regular function. 761 // Invoke a regular function.
850 __ bind(&regular_invoke); 762 __ bind(&regular_invoke);
851 if (can_do_fast_api_call) { 763 if (can_do_fast_api_call) {
852 FreeSpaceForFastApiCall(masm); 764 FreeSpaceForFastApiCall(masm);
853 } 765 }
854
855 return masm->isolate()->heap()->undefined_value();
856 } 766 }
857 767
858 void CompileRegular(MacroAssembler* masm, 768 void CompileRegular(MacroAssembler* masm,
859 JSObject* object, 769 Handle<JSObject> object,
860 Register receiver, 770 Register receiver,
861 Register scratch1, 771 Register scratch1,
862 Register scratch2, 772 Register scratch2,
863 Register scratch3, 773 Register scratch3,
864 String* name, 774 Handle<String> name,
865 JSObject* interceptor_holder, 775 Handle<JSObject> interceptor_holder,
866 Label* miss_label) { 776 Label* miss_label) {
867 Register holder = 777 Register holder =
868 stub_compiler_->CheckPrototypes(object, receiver, interceptor_holder, 778 stub_compiler_->CheckPrototypes(object, receiver, interceptor_holder,
869 scratch1, scratch2, scratch3, name, 779 scratch1, scratch2, scratch3,
870 miss_label); 780 name, miss_label);
871 781
872 // Call a runtime function to load the interceptor property. 782 // Call a runtime function to load the interceptor property.
873 FrameScope scope(masm, StackFrame::INTERNAL); 783 FrameScope scope(masm, StackFrame::INTERNAL);
874 // Save the name_ register across the call. 784 // Save the name_ register across the call.
875 __ push(name_); 785 __ push(name_);
876 786
877 PushInterceptorArguments(masm, 787 PushInterceptorArguments(masm, receiver, holder, name_, interceptor_holder);
878 receiver,
879 holder,
880 name_,
881 interceptor_holder);
882 788
883 __ CallExternalReference( 789 __ CallExternalReference(
884 ExternalReference( 790 ExternalReference(
885 IC_Utility(IC::kLoadPropertyWithInterceptorForCall), 791 IC_Utility(IC::kLoadPropertyWithInterceptorForCall),
886 masm->isolate()), 792 masm->isolate()),
887 5); 793 5);
888
889 // Restore the name_ register. 794 // Restore the name_ register.
890 __ pop(name_); 795 __ pop(name_);
891
892 // Leave the internal frame. 796 // Leave the internal frame.
893 } 797 }
894 798
895 void LoadWithInterceptor(MacroAssembler* masm, 799 void LoadWithInterceptor(MacroAssembler* masm,
896 Register receiver, 800 Register receiver,
897 Register holder, 801 Register holder,
898 JSObject* holder_obj, 802 Handle<JSObject> holder_obj,
899 Register scratch, 803 Register scratch,
900 Label* interceptor_succeeded) { 804 Label* interceptor_succeeded) {
901 { 805 {
902 FrameScope scope(masm, StackFrame::INTERNAL); 806 FrameScope scope(masm, StackFrame::INTERNAL);
903 807
904 __ Push(holder, name_); 808 __ Push(holder, name_);
905
906 CompileCallLoadPropertyWithInterceptor(masm, 809 CompileCallLoadPropertyWithInterceptor(masm,
907 receiver, 810 receiver,
908 holder, 811 holder,
909 name_, 812 name_,
910 holder_obj); 813 holder_obj);
911
912 __ pop(name_); // Restore the name. 814 __ pop(name_); // Restore the name.
913 __ pop(receiver); // Restore the holder. 815 __ pop(receiver); // Restore the holder.
914 } 816 }
915
916 // If interceptor returns no-result sentinel, call the constant function. 817 // If interceptor returns no-result sentinel, call the constant function.
917 __ LoadRoot(scratch, Heap::kNoInterceptorResultSentinelRootIndex); 818 __ LoadRoot(scratch, Heap::kNoInterceptorResultSentinelRootIndex);
918 __ Branch(interceptor_succeeded, ne, v0, Operand(scratch)); 819 __ Branch(interceptor_succeeded, ne, v0, Operand(scratch));
919 } 820 }
920 821
921 StubCompiler* stub_compiler_; 822 StubCompiler* stub_compiler_;
922 const ParameterCount& arguments_; 823 const ParameterCount& arguments_;
923 Register name_; 824 Register name_;
924 Code::ExtraICState extra_ic_state_; 825 Code::ExtraICState extra_ic_state_;
925 }; 826 };
(...skipping 12 matching lines...) Expand all
938 GlobalObject::EnsurePropertyCell(global, name); 839 GlobalObject::EnsurePropertyCell(global, name);
939 ASSERT(cell->value()->IsTheHole()); 840 ASSERT(cell->value()->IsTheHole());
940 __ li(scratch, Operand(cell)); 841 __ li(scratch, Operand(cell));
941 __ lw(scratch, 842 __ lw(scratch,
942 FieldMemOperand(scratch, JSGlobalPropertyCell::kValueOffset)); 843 FieldMemOperand(scratch, JSGlobalPropertyCell::kValueOffset));
943 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 844 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
944 __ Branch(miss, ne, scratch, Operand(at)); 845 __ Branch(miss, ne, scratch, Operand(at));
945 } 846 }
946 847
947 848
948 // TODO(kmillikin): Eliminate this function when the stub cache is fully
949 // handlified.
950 MUST_USE_RESULT static MaybeObject* TryGenerateCheckPropertyCell(
951 MacroAssembler* masm,
952 GlobalObject* global,
953 String* name,
954 Register scratch,
955 Label* miss) {
956 Object* probe;
957 { MaybeObject* maybe_probe = global->EnsurePropertyCell(name);
958 if (!maybe_probe->ToObject(&probe)) return maybe_probe;
959 }
960 JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(probe);
961 ASSERT(cell->value()->IsTheHole());
962 __ li(scratch, Operand(Handle<Object>(cell)));
963 __ lw(scratch,
964 FieldMemOperand(scratch, JSGlobalPropertyCell::kValueOffset));
965 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
966 __ Branch(miss, ne, scratch, Operand(at));
967 return cell;
968 }
969
970
971 // Calls GenerateCheckPropertyCell for each global object in the prototype chain 849 // Calls GenerateCheckPropertyCell for each global object in the prototype chain
972 // from object to (but not including) holder. 850 // from object to (but not including) holder.
973 static void GenerateCheckPropertyCells(MacroAssembler* masm, 851 static void GenerateCheckPropertyCells(MacroAssembler* masm,
974 Handle<JSObject> object, 852 Handle<JSObject> object,
975 Handle<JSObject> holder, 853 Handle<JSObject> holder,
976 Handle<String> name, 854 Handle<String> name,
977 Register scratch, 855 Register scratch,
978 Label* miss) { 856 Label* miss) {
979 Handle<JSObject> current = object; 857 Handle<JSObject> current = object;
980 while (!current.is_identical_to(holder)) { 858 while (!current.is_identical_to(holder)) {
981 if (current->IsGlobalObject()) { 859 if (current->IsGlobalObject()) {
982 GenerateCheckPropertyCell(masm, 860 GenerateCheckPropertyCell(masm,
983 Handle<GlobalObject>::cast(current), 861 Handle<GlobalObject>::cast(current),
984 name, 862 name,
985 scratch, 863 scratch,
986 miss); 864 miss);
987 } 865 }
988 current = Handle<JSObject>(JSObject::cast(current->GetPrototype())); 866 current = Handle<JSObject>(JSObject::cast(current->GetPrototype()));
989 } 867 }
990 } 868 }
991 869
992 870
993 // TODO(kmillikin): Eliminate this function when the stub cache is fully
994 // handlified.
995 MUST_USE_RESULT static MaybeObject* TryGenerateCheckPropertyCells(
996 MacroAssembler* masm,
997 JSObject* object,
998 JSObject* holder,
999 String* name,
1000 Register scratch,
1001 Label* miss) {
1002 JSObject* current = object;
1003 while (current != holder) {
1004 if (current->IsGlobalObject()) {
1005 // Returns a cell or a failure.
1006 MaybeObject* result = TryGenerateCheckPropertyCell(
1007 masm,
1008 GlobalObject::cast(current),
1009 name,
1010 scratch,
1011 miss);
1012 if (result->IsFailure()) return result;
1013 }
1014 ASSERT(current->IsJSObject());
1015 current = JSObject::cast(current->GetPrototype());
1016 }
1017 return NULL;
1018 }
1019
1020
1021 // Convert and store int passed in register ival to IEEE 754 single precision 871 // Convert and store int passed in register ival to IEEE 754 single precision
1022 // floating point value at memory location (dst + 4 * wordoffset) 872 // floating point value at memory location (dst + 4 * wordoffset)
1023 // If FPU is available use it for conversion. 873 // If FPU is available use it for conversion.
1024 static void StoreIntAsFloat(MacroAssembler* masm, 874 static void StoreIntAsFloat(MacroAssembler* masm,
1025 Register dst, 875 Register dst,
1026 Register wordoffset, 876 Register wordoffset,
1027 Register ival, 877 Register ival,
1028 Register fval, 878 Register fval,
1029 Register scratch1, 879 Register scratch1,
1030 Register scratch2) { 880 Register scratch2) {
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
1233 // If we've skipped any global objects, it's not enough to verify that 1083 // If we've skipped any global objects, it's not enough to verify that
1234 // their maps haven't changed. We also need to check that the property 1084 // their maps haven't changed. We also need to check that the property
1235 // cell for the property is still empty. 1085 // cell for the property is still empty.
1236 GenerateCheckPropertyCells(masm(), object, holder, name, scratch1, miss); 1086 GenerateCheckPropertyCells(masm(), object, holder, name, scratch1, miss);
1237 1087
1238 // Return the register containing the holder. 1088 // Return the register containing the holder.
1239 return reg; 1089 return reg;
1240 } 1090 }
1241 1091
1242 1092
1243 Register StubCompiler::CheckPrototypes(JSObject* object,
1244 Register object_reg,
1245 JSObject* holder,
1246 Register holder_reg,
1247 Register scratch1,
1248 Register scratch2,
1249 String* name,
1250 int save_at_depth,
1251 Label* miss) {
1252 // Make sure there's no overlap between holder and object registers.
1253 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg));
1254 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg)
1255 && !scratch2.is(scratch1));
1256
1257 // Keep track of the current object in register reg.
1258 Register reg = object_reg;
1259 int depth = 0;
1260
1261 if (save_at_depth == depth) {
1262 __ sw(reg, MemOperand(sp));
1263 }
1264
1265 // Check the maps in the prototype chain.
1266 // Traverse the prototype chain from the object and do map checks.
1267 JSObject* current = object;
1268 while (current != holder) {
1269 depth++;
1270
1271 // Only global objects and objects that do not require access
1272 // checks are allowed in stubs.
1273 ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded());
1274
1275 ASSERT(current->GetPrototype()->IsJSObject());
1276 JSObject* prototype = JSObject::cast(current->GetPrototype());
1277 if (!current->HasFastProperties() &&
1278 !current->IsJSGlobalObject() &&
1279 !current->IsJSGlobalProxy()) {
1280 if (!name->IsSymbol()) {
1281 MaybeObject* maybe_lookup_result = heap()->LookupSymbol(name);
1282 Object* lookup_result = NULL; // Initialization to please compiler.
1283 if (!maybe_lookup_result->ToObject(&lookup_result)) {
1284 set_failure(Failure::cast(maybe_lookup_result));
1285 return reg;
1286 }
1287 name = String::cast(lookup_result);
1288 }
1289 ASSERT(current->property_dictionary()->FindEntry(name) ==
1290 StringDictionary::kNotFound);
1291
1292 MaybeObject* negative_lookup =
1293 TryGenerateDictionaryNegativeLookup(masm(),
1294 miss,
1295 reg,
1296 name,
1297 scratch1,
1298 scratch2);
1299
1300 if (negative_lookup->IsFailure()) {
1301 set_failure(Failure::cast(negative_lookup));
1302 return reg;
1303 }
1304
1305 __ lw(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset));
1306 reg = holder_reg; // From now the object is in holder_reg.
1307 __ lw(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset));
1308 } else if (heap()->InNewSpace(prototype)) {
1309 // Get the map of the current object.
1310 __ lw(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset));
1311
1312 // Branch on the result of the map check.
1313 __ Branch(miss, ne, scratch1, Operand(Handle<Map>(current->map())));
1314
1315 // Check access rights to the global object. This has to happen
1316 // after the map check so that we know that the object is
1317 // actually a global object.
1318 if (current->IsJSGlobalProxy()) {
1319 __ CheckAccessGlobalProxy(reg, scratch1, miss);
1320 // Restore scratch register to be the map of the object. In the
1321 // new space case below, we load the prototype from the map in
1322 // the scratch register.
1323 __ lw(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset));
1324 }
1325
1326 reg = holder_reg; // From now the object is in holder_reg.
1327 // The prototype is in new space; we cannot store a reference
1328 // to it in the code. Load it from the map.
1329 __ lw(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset));
1330 } else {
1331 // Check the map of the current object.
1332 __ lw(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset));
1333 // Branch on the result of the map check.
1334 __ Branch(miss, ne, scratch1, Operand(Handle<Map>(current->map())));
1335 // Check access rights to the global object. This has to happen
1336 // after the map check so that we know that the object is
1337 // actually a global object.
1338 if (current->IsJSGlobalProxy()) {
1339 __ CheckAccessGlobalProxy(reg, scratch1, miss);
1340 }
1341 // The prototype is in old space; load it directly.
1342 reg = holder_reg; // From now the object is in holder_reg.
1343 __ li(reg, Operand(Handle<JSObject>(prototype)));
1344 }
1345
1346 if (save_at_depth == depth) {
1347 __ sw(reg, MemOperand(sp));
1348 }
1349
1350 // Go to the next object in the prototype chain.
1351 current = prototype;
1352 }
1353
1354 // Check the holder map.
1355 __ lw(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset));
1356 __ Branch(miss, ne, scratch1, Operand(Handle<Map>(current->map())));
1357
1358 // Log the check depth.
1359 LOG(masm()->isolate(), IntEvent("check-maps-depth", depth + 1));
1360 // Perform security check for access to the global object.
1361 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded());
1362 if (holder->IsJSGlobalProxy()) {
1363 __ CheckAccessGlobalProxy(reg, scratch1, miss);
1364 }
1365
1366 // If we've skipped any global objects, it's not enough to verify
1367 // that their maps haven't changed. We also need to check that the
1368 // property cell for the property is still empty.
1369
1370 MaybeObject* result = TryGenerateCheckPropertyCells(masm(),
1371 object,
1372 holder,
1373 name,
1374 scratch1,
1375 miss);
1376 if (result->IsFailure()) set_failure(Failure::cast(result));
1377
1378 // Return the register containing the holder.
1379 return reg;
1380 }
1381
1382
1383 void StubCompiler::GenerateLoadField(Handle<JSObject> object, 1093 void StubCompiler::GenerateLoadField(Handle<JSObject> object,
1384 Handle<JSObject> holder, 1094 Handle<JSObject> holder,
1385 Register receiver, 1095 Register receiver,
1386 Register scratch1, 1096 Register scratch1,
1387 Register scratch2, 1097 Register scratch2,
1388 Register scratch3, 1098 Register scratch3,
1389 int index, 1099 int index,
1390 Handle<String> name, 1100 Handle<String> name,
1391 Label* miss) { 1101 Label* miss) {
1392 // Check that the receiver isn't a smi. 1102 // Check that the receiver isn't a smi.
(...skipping 24 matching lines...) Expand all
1417 Register reg = 1127 Register reg =
1418 CheckPrototypes(object, receiver, holder, 1128 CheckPrototypes(object, receiver, holder,
1419 scratch1, scratch2, scratch3, name, miss); 1129 scratch1, scratch2, scratch3, name, miss);
1420 1130
1421 // Return the constant value. 1131 // Return the constant value.
1422 __ li(v0, Operand(value)); 1132 __ li(v0, Operand(value));
1423 __ Ret(); 1133 __ Ret();
1424 } 1134 }
1425 1135
1426 1136
1427 MaybeObject* StubCompiler::GenerateLoadCallback(JSObject* object, 1137 void StubCompiler::GenerateLoadCallback(Handle<JSObject> object,
1428 JSObject* holder, 1138 Handle<JSObject> holder,
1429 Register receiver, 1139 Register receiver,
1430 Register name_reg, 1140 Register name_reg,
1431 Register scratch1, 1141 Register scratch1,
1432 Register scratch2, 1142 Register scratch2,
1433 Register scratch3, 1143 Register scratch3,
1434 AccessorInfo* callback, 1144 Handle<AccessorInfo> callback,
1435 String* name, 1145 Handle<String> name,
1436 Label* miss) { 1146 Label* miss) {
1437 // Check that the receiver isn't a smi. 1147 // Check that the receiver isn't a smi.
1438 __ JumpIfSmi(receiver, miss, scratch1); 1148 __ JumpIfSmi(receiver, miss, scratch1);
1439 1149
1440 // Check that the maps haven't changed. 1150 // Check that the maps haven't changed.
1441 Register reg = 1151 Register reg = CheckPrototypes(object, receiver, holder, scratch1,
1442 CheckPrototypes(object, receiver, holder, scratch1, scratch2, scratch3, 1152 scratch2, scratch3, name, miss);
1443 name, miss);
1444 1153
1445 // Build AccessorInfo::args_ list on the stack and push property name below 1154 // Build AccessorInfo::args_ list on the stack and push property name below
1446 // the exit frame to make GC aware of them and store pointers to them. 1155 // the exit frame to make GC aware of them and store pointers to them.
1447 __ push(receiver); 1156 __ push(receiver);
1448 __ mov(scratch2, sp); // scratch2 = AccessorInfo::args_ 1157 __ mov(scratch2, sp); // scratch2 = AccessorInfo::args_
1449 Handle<AccessorInfo> callback_handle(callback); 1158 if (heap()->InNewSpace(callback->data())) {
1450 if (heap()->InNewSpace(callback_handle->data())) { 1159 __ li(scratch3, callback);
1451 __ li(scratch3, callback_handle);
1452 __ lw(scratch3, FieldMemOperand(scratch3, AccessorInfo::kDataOffset)); 1160 __ lw(scratch3, FieldMemOperand(scratch3, AccessorInfo::kDataOffset));
1453 } else { 1161 } else {
1454 __ li(scratch3, Handle<Object>(callback_handle->data())); 1162 __ li(scratch3, Handle<Object>(callback->data()));
1455 } 1163 }
1456 __ Push(reg, scratch3, name_reg); 1164 __ Push(reg, scratch3, name_reg);
1457 __ mov(a2, scratch2); // Saved in case scratch2 == a1. 1165 __ mov(a2, scratch2); // Saved in case scratch2 == a1.
1458 __ mov(a1, sp); // a1 (first argument - see note below) = Handle<String> 1166 __ mov(a1, sp); // a1 (first argument - see note below) = Handle<String>
1459 1167
1460 Address getter_address = v8::ToCData<Address>(callback->getter());
1461 ApiFunction fun(getter_address);
1462
1463 // NOTE: the O32 abi requires a0 to hold a special pointer when returning a 1168 // NOTE: the O32 abi requires a0 to hold a special pointer when returning a
1464 // struct from the function (which is currently the case). This means we pass 1169 // struct from the function (which is currently the case). This means we pass
1465 // the arguments in a1-a2 instead of a0-a1. TryCallApiFunctionAndReturn 1170 // the arguments in a1-a2 instead of a0-a1. TryCallApiFunctionAndReturn
1466 // will handle setting up a0. 1171 // will handle setting up a0.
1467 1172
1468 const int kApiStackSpace = 1; 1173 const int kApiStackSpace = 1;
1469
1470 FrameScope frame_scope(masm(), StackFrame::MANUAL); 1174 FrameScope frame_scope(masm(), StackFrame::MANUAL);
1471 __ EnterExitFrame(false, kApiStackSpace); 1175 __ EnterExitFrame(false, kApiStackSpace);
1472 1176
1473 // Create AccessorInfo instance on the stack above the exit frame with 1177 // Create AccessorInfo instance on the stack above the exit frame with
1474 // scratch2 (internal::Object **args_) as the data. 1178 // scratch2 (internal::Object **args_) as the data.
1475 __ sw(a2, MemOperand(sp, kPointerSize)); 1179 __ sw(a2, MemOperand(sp, kPointerSize));
1476 // a2 (second argument - see note above) = AccessorInfo& 1180 // a2 (second argument - see note above) = AccessorInfo&
1477 __ Addu(a2, sp, kPointerSize); 1181 __ Addu(a2, sp, kPointerSize);
1478 1182
1479 // Emitting a stub call may try to allocate (if the code is not 1183 const int kStackUnwindSpace = 4;
1480 // already generated). Do not allow the assembler to perform a 1184 Address getter_address = v8::ToCData<Address>(callback->getter());
1481 // garbage collection but instead return the allocation failure 1185 ApiFunction fun(getter_address);
1482 // object.
1483 ExternalReference ref = 1186 ExternalReference ref =
1484 ExternalReference(&fun, 1187 ExternalReference(&fun,
1485 ExternalReference::DIRECT_GETTER_CALL, 1188 ExternalReference::DIRECT_GETTER_CALL,
1486 masm()->isolate()); 1189 masm()->isolate());
1487 // 4 args - will be freed later by LeaveExitFrame. 1190 __ CallApiFunctionAndReturn(ref, kStackUnwindSpace);
1488 return masm()->TryCallApiFunctionAndReturn(ref, 4);
1489 } 1191 }
1490 1192
1491 1193
1492 void StubCompiler::GenerateLoadInterceptor(JSObject* object, 1194 void StubCompiler::GenerateLoadInterceptor(Handle<JSObject> object,
1493 JSObject* interceptor_holder, 1195 Handle<JSObject> interceptor_holder,
1494 LookupResult* lookup, 1196 LookupResult* lookup,
1495 Register receiver, 1197 Register receiver,
1496 Register name_reg, 1198 Register name_reg,
1497 Register scratch1, 1199 Register scratch1,
1498 Register scratch2, 1200 Register scratch2,
1499 Register scratch3, 1201 Register scratch3,
1500 String* name, 1202 Handle<String> name,
1501 Label* miss) { 1203 Label* miss) {
1502 ASSERT(interceptor_holder->HasNamedInterceptor()); 1204 ASSERT(interceptor_holder->HasNamedInterceptor());
1503 ASSERT(!interceptor_holder->GetNamedInterceptor()->getter()->IsUndefined()); 1205 ASSERT(!interceptor_holder->GetNamedInterceptor()->getter()->IsUndefined());
1504 1206
1505 // Check that the receiver isn't a smi. 1207 // Check that the receiver isn't a smi.
1506 __ JumpIfSmi(receiver, miss); 1208 __ JumpIfSmi(receiver, miss);
1507 1209
1508 // So far the most popular follow ups for interceptor loads are FIELD 1210 // So far the most popular follow ups for interceptor loads are FIELD
1509 // and CALLBACKS, so inline only them, other cases may be added 1211 // and CALLBACKS, so inline only them, other cases may be added
1510 // later. 1212 // later.
1511 bool compile_followup_inline = false; 1213 bool compile_followup_inline = false;
1512 if (lookup->IsProperty() && lookup->IsCacheable()) { 1214 if (lookup->IsProperty() && lookup->IsCacheable()) {
1513 if (lookup->type() == FIELD) { 1215 if (lookup->type() == FIELD) {
1514 compile_followup_inline = true; 1216 compile_followup_inline = true;
1515 } else if (lookup->type() == CALLBACKS && 1217 } else if (lookup->type() == CALLBACKS &&
1516 lookup->GetCallbackObject()->IsAccessorInfo() && 1218 lookup->GetCallbackObject()->IsAccessorInfo()) {
1517 AccessorInfo::cast(lookup->GetCallbackObject())->getter() != NULL) { 1219 compile_followup_inline =
1518 compile_followup_inline = true; 1220 AccessorInfo::cast(lookup->GetCallbackObject())->getter() != NULL;
1519 } 1221 }
1520 } 1222 }
1521 1223
1522 if (compile_followup_inline) { 1224 if (compile_followup_inline) {
1523 // Compile the interceptor call, followed by inline code to load the 1225 // Compile the interceptor call, followed by inline code to load the
1524 // property from further up the prototype chain if the call fails. 1226 // property from further up the prototype chain if the call fails.
1525 // Check that the maps haven't changed. 1227 // Check that the maps haven't changed.
1526 Register holder_reg = CheckPrototypes(object, receiver, interceptor_holder, 1228 Register holder_reg = CheckPrototypes(object, receiver, interceptor_holder,
1527 scratch1, scratch2, scratch3, 1229 scratch1, scratch2, scratch3,
1528 name, miss); 1230 name, miss);
1529 ASSERT(holder_reg.is(receiver) || holder_reg.is(scratch1)); 1231 ASSERT(holder_reg.is(receiver) || holder_reg.is(scratch1));
1530 1232
1531 // Save necessary data before invoking an interceptor. 1233 // Save necessary data before invoking an interceptor.
1532 // Requires a frame to make GC aware of pushed pointers. 1234 // Requires a frame to make GC aware of pushed pointers.
1533 { 1235 {
1534 FrameScope frame_scope(masm(), StackFrame::INTERNAL); 1236 FrameScope frame_scope(masm(), StackFrame::INTERNAL);
1535
1536 if (lookup->type() == CALLBACKS && !receiver.is(holder_reg)) { 1237 if (lookup->type() == CALLBACKS && !receiver.is(holder_reg)) {
1537 // CALLBACKS case needs a receiver to be passed into C++ callback. 1238 // CALLBACKS case needs a receiver to be passed into C++ callback.
1538 __ Push(receiver, holder_reg, name_reg); 1239 __ Push(receiver, holder_reg, name_reg);
1539 } else { 1240 } else {
1540 __ Push(holder_reg, name_reg); 1241 __ Push(holder_reg, name_reg);
1541 } 1242 }
1542
1543 // Invoke an interceptor. Note: map checks from receiver to 1243 // Invoke an interceptor. Note: map checks from receiver to
1544 // interceptor's holder has been compiled before (see a caller 1244 // interceptor's holder has been compiled before (see a caller
1545 // of this method). 1245 // of this method).
1546 CompileCallLoadPropertyWithInterceptor(masm(), 1246 CompileCallLoadPropertyWithInterceptor(masm(),
1547 receiver, 1247 receiver,
1548 holder_reg, 1248 holder_reg,
1549 name_reg, 1249 name_reg,
1550 interceptor_holder); 1250 interceptor_holder);
1551
1552 // Check if interceptor provided a value for property. If it's 1251 // Check if interceptor provided a value for property. If it's
1553 // the case, return immediately. 1252 // the case, return immediately.
1554 Label interceptor_failed; 1253 Label interceptor_failed;
1555 __ LoadRoot(scratch1, Heap::kNoInterceptorResultSentinelRootIndex); 1254 __ LoadRoot(scratch1, Heap::kNoInterceptorResultSentinelRootIndex);
1556 __ Branch(&interceptor_failed, eq, v0, Operand(scratch1)); 1255 __ Branch(&interceptor_failed, eq, v0, Operand(scratch1));
1557 frame_scope.GenerateLeaveFrame(); 1256 frame_scope.GenerateLeaveFrame();
1558 __ Ret(); 1257 __ Ret();
1559 1258
1560 __ bind(&interceptor_failed); 1259 __ bind(&interceptor_failed);
1561 __ pop(name_reg); 1260 __ pop(name_reg);
1562 __ pop(holder_reg); 1261 __ pop(holder_reg);
1563 if (lookup->type() == CALLBACKS && !receiver.is(holder_reg)) { 1262 if (lookup->type() == CALLBACKS && !receiver.is(holder_reg)) {
1564 __ pop(receiver); 1263 __ pop(receiver);
1565 } 1264 }
1566
1567 // Leave the internal frame. 1265 // Leave the internal frame.
1568 } 1266 }
1569
1570 // Check that the maps from interceptor's holder to lookup's holder 1267 // Check that the maps from interceptor's holder to lookup's holder
1571 // haven't changed. And load lookup's holder into |holder| register. 1268 // haven't changed. And load lookup's holder into |holder| register.
1572 if (interceptor_holder != lookup->holder()) { 1269 if (*interceptor_holder != lookup->holder()) {
1573 holder_reg = CheckPrototypes(interceptor_holder, 1270 holder_reg = CheckPrototypes(interceptor_holder,
1574 holder_reg, 1271 holder_reg,
1575 lookup->holder(), 1272 Handle<JSObject>(lookup->holder()),
1576 scratch1, 1273 scratch1,
1577 scratch2, 1274 scratch2,
1578 scratch3, 1275 scratch3,
1579 name, 1276 name,
1580 miss); 1277 miss);
1581 } 1278 }
1582 1279
1583 if (lookup->type() == FIELD) { 1280 if (lookup->type() == FIELD) {
1584 // We found FIELD property in prototype chain of interceptor's holder. 1281 // We found FIELD property in prototype chain of interceptor's holder.
1585 // Retrieve a field from field's holder. 1282 // Retrieve a field from field's holder.
1586 GenerateFastPropertyLoad(masm(), v0, holder_reg, 1283 GenerateFastPropertyLoad(masm(), v0, holder_reg,
1587 Handle<JSObject>(lookup->holder()), 1284 Handle<JSObject>(lookup->holder()),
1588 lookup->GetFieldIndex()); 1285 lookup->GetFieldIndex());
1589 __ Ret(); 1286 __ Ret();
1590 } else { 1287 } else {
1591 // We found CALLBACKS property in prototype chain of interceptor's 1288 // We found CALLBACKS property in prototype chain of interceptor's
1592 // holder. 1289 // holder.
1593 ASSERT(lookup->type() == CALLBACKS); 1290 ASSERT(lookup->type() == CALLBACKS);
1594 ASSERT(lookup->GetCallbackObject()->IsAccessorInfo()); 1291 Handle<AccessorInfo> callback(
1595 AccessorInfo* callback = AccessorInfo::cast(lookup->GetCallbackObject()); 1292 AccessorInfo::cast(lookup->GetCallbackObject()));
1596 ASSERT(callback != NULL);
1597 ASSERT(callback->getter() != NULL); 1293 ASSERT(callback->getter() != NULL);
1598 1294
1599 // Tail call to runtime. 1295 // Tail call to runtime.
1600 // Important invariant in CALLBACKS case: the code above must be 1296 // Important invariant in CALLBACKS case: the code above must be
1601 // structured to never clobber |receiver| register. 1297 // structured to never clobber |receiver| register.
1602 __ li(scratch2, Handle<AccessorInfo>(callback)); 1298 __ li(scratch2, callback);
1603 // holder_reg is either receiver or scratch1. 1299 // holder_reg is either receiver or scratch1.
1604 if (!receiver.is(holder_reg)) { 1300 if (!receiver.is(holder_reg)) {
1605 ASSERT(scratch1.is(holder_reg)); 1301 ASSERT(scratch1.is(holder_reg));
1606 __ Push(receiver, holder_reg); 1302 __ Push(receiver, holder_reg);
1607 __ lw(scratch3, 1303 __ lw(scratch3,
1608 FieldMemOperand(scratch2, AccessorInfo::kDataOffset)); 1304 FieldMemOperand(scratch2, AccessorInfo::kDataOffset));
1609 __ Push(scratch3, scratch2, name_reg); 1305 __ Push(scratch3, scratch2, name_reg);
1610 } else { 1306 } else {
1611 __ push(receiver); 1307 __ push(receiver);
1612 __ lw(scratch3, 1308 __ lw(scratch3,
(...skipping 22 matching lines...) Expand all
1635 } 1331 }
1636 1332
1637 1333
1638 void CallStubCompiler::GenerateNameCheck(Handle<String> name, Label* miss) { 1334 void CallStubCompiler::GenerateNameCheck(Handle<String> name, Label* miss) {
1639 if (kind_ == Code::KEYED_CALL_IC) { 1335 if (kind_ == Code::KEYED_CALL_IC) {
1640 __ Branch(miss, ne, a2, Operand(name)); 1336 __ Branch(miss, ne, a2, Operand(name));
1641 } 1337 }
1642 } 1338 }
1643 1339
1644 1340
1645 void CallStubCompiler::GenerateGlobalReceiverCheck(JSObject* object, 1341 void CallStubCompiler::GenerateGlobalReceiverCheck(Handle<JSObject> object,
1646 JSObject* holder, 1342 Handle<JSObject> holder,
1647 String* name, 1343 Handle<String> name,
1648 Label* miss) { 1344 Label* miss) {
1649 ASSERT(holder->IsGlobalObject()); 1345 ASSERT(holder->IsGlobalObject());
1650 1346
1651 // Get the number of arguments. 1347 // Get the number of arguments.
1652 const int argc = arguments().immediate(); 1348 const int argc = arguments().immediate();
1653 1349
1654 // Get the receiver from the stack. 1350 // Get the receiver from the stack.
1655 __ lw(a0, MemOperand(sp, argc * kPointerSize)); 1351 __ lw(a0, MemOperand(sp, argc * kPointerSize));
1656 1352
1657 // If the object is the holder then we know that it's a global 1353 // If the object is the holder then we know that it's a global
1658 // object which can only happen for contextual calls. In this case, 1354 // object which can only happen for contextual calls. In this case,
1659 // the receiver cannot be a smi. 1355 // the receiver cannot be a smi.
1660 if (object != holder) { 1356 if (!object.is_identical_to(holder)) {
1661 __ JumpIfSmi(a0, miss); 1357 __ JumpIfSmi(a0, miss);
1662 } 1358 }
1663 1359
1664 // Check that the maps haven't changed. 1360 // Check that the maps haven't changed.
1665 CheckPrototypes(object, a0, holder, a3, a1, t0, name, miss); 1361 CheckPrototypes(object, a0, holder, a3, a1, t0, name, miss);
1666 } 1362 }
1667 1363
1668 1364
1669 void CallStubCompiler::GenerateLoadFunctionFromCell(JSGlobalPropertyCell* cell, 1365 void CallStubCompiler::GenerateLoadFunctionFromCell(
1670 JSFunction* function, 1366 Handle<JSGlobalPropertyCell> cell,
1671 Label* miss) { 1367 Handle<JSFunction> function,
1368 Label* miss) {
1672 // Get the value from the cell. 1369 // Get the value from the cell.
1673 __ li(a3, Operand(Handle<JSGlobalPropertyCell>(cell))); 1370 __ li(a3, Operand(cell));
1674 __ lw(a1, FieldMemOperand(a3, JSGlobalPropertyCell::kValueOffset)); 1371 __ lw(a1, FieldMemOperand(a3, JSGlobalPropertyCell::kValueOffset));
1675 1372
1676 // Check that the cell contains the same function. 1373 // Check that the cell contains the same function.
1677 if (heap()->InNewSpace(function)) { 1374 if (heap()->InNewSpace(*function)) {
1678 // We can't embed a pointer to a function in new space so we have 1375 // We can't embed a pointer to a function in new space so we have
1679 // to verify that the shared function info is unchanged. This has 1376 // to verify that the shared function info is unchanged. This has
1680 // the nice side effect that multiple closures based on the same 1377 // the nice side effect that multiple closures based on the same
1681 // function can all use this call IC. Before we load through the 1378 // function can all use this call IC. Before we load through the
1682 // function, we have to verify that it still is a function. 1379 // function, we have to verify that it still is a function.
1683 __ JumpIfSmi(a1, miss); 1380 __ JumpIfSmi(a1, miss);
1684 __ GetObjectType(a1, a3, a3); 1381 __ GetObjectType(a1, a3, a3);
1685 __ Branch(miss, ne, a3, Operand(JS_FUNCTION_TYPE)); 1382 __ Branch(miss, ne, a3, Operand(JS_FUNCTION_TYPE));
1686 1383
1687 // Check the shared function info. Make sure it hasn't changed. 1384 // Check the shared function info. Make sure it hasn't changed.
1688 __ li(a3, Handle<SharedFunctionInfo>(function->shared())); 1385 __ li(a3, Handle<SharedFunctionInfo>(function->shared()));
1689 __ lw(t0, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); 1386 __ lw(t0, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
1690 __ Branch(miss, ne, t0, Operand(a3)); 1387 __ Branch(miss, ne, t0, Operand(a3));
1691 } else { 1388 } else {
1692 __ Branch(miss, ne, a1, Operand(Handle<JSFunction>(function))); 1389 __ Branch(miss, ne, a1, Operand(function));
1693 } 1390 }
1694 } 1391 }
1695 1392
1696 1393
1697 void CallStubCompiler::GenerateMissBranch() { 1394 void CallStubCompiler::GenerateMissBranch() {
1698 Handle<Code> code = 1395 Handle<Code> code =
1699 isolate()->stub_cache()->ComputeCallMiss(arguments().immediate(), 1396 isolate()->stub_cache()->ComputeCallMiss(arguments().immediate(),
1700 kind_, 1397 kind_,
1701 extra_state_); 1398 extra_state_);
1702 __ Jump(code, RelocInfo::CODE_TARGET); 1399 __ Jump(code, RelocInfo::CODE_TARGET);
1703 } 1400 }
1704 1401
1705 1402
1706 // TODO(kmillikin): Eliminate this function when the stub cache is fully
1707 // handlified.
1708 MaybeObject* CallStubCompiler::TryGenerateMissBranch() {
1709 MaybeObject* maybe_obj =
1710 isolate()->stub_cache()->TryComputeCallMiss(arguments().immediate(),
1711 kind_,
1712 extra_state_);
1713 Object* obj;
1714 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
1715 __ Jump(Handle<Code>(Code::cast(obj)), RelocInfo::CODE_TARGET);
1716 return obj;
1717 }
1718
1719
1720 Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object, 1403 Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object,
1721 Handle<JSObject> holder, 1404 Handle<JSObject> holder,
1722 int index, 1405 int index,
1723 Handle<String> name) { 1406 Handle<String> name) {
1724 // ----------- S t a t e ------------- 1407 // ----------- S t a t e -------------
1725 // -- a2 : name 1408 // -- a2 : name
1726 // -- ra : return address 1409 // -- ra : return address
1727 // ----------------------------------- 1410 // -----------------------------------
1728 Label miss; 1411 Label miss;
1729 1412
(...skipping 14 matching lines...) Expand all
1744 1427
1745 // Handle call cache miss. 1428 // Handle call cache miss.
1746 __ bind(&miss); 1429 __ bind(&miss);
1747 GenerateMissBranch(); 1430 GenerateMissBranch();
1748 1431
1749 // Return the generated code. 1432 // Return the generated code.
1750 return GetCode(FIELD, name); 1433 return GetCode(FIELD, name);
1751 } 1434 }
1752 1435
1753 1436
1754 MaybeObject* CallStubCompiler::CompileArrayPushCall(Object* object, 1437 Handle<Code> CallStubCompiler::CompileArrayPushCall(
1755 JSObject* holder, 1438 Handle<Object> object,
1756 JSGlobalPropertyCell* cell, 1439 Handle<JSObject> holder,
1757 JSFunction* function, 1440 Handle<JSGlobalPropertyCell> cell,
1758 String* name) { 1441 Handle<JSFunction> function,
1442 Handle<String> name) {
1759 // ----------- S t a t e ------------- 1443 // ----------- S t a t e -------------
1760 // -- a2 : name 1444 // -- a2 : name
1761 // -- ra : return address 1445 // -- ra : return address
1762 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) 1446 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based)
1763 // -- ... 1447 // -- ...
1764 // -- sp[argc * 4] : receiver 1448 // -- sp[argc * 4] : receiver
1765 // ----------------------------------- 1449 // -----------------------------------
1766 1450
1767 // If object is not an array, bail out to regular call. 1451 // If object is not an array, bail out to regular call.
1768 if (!object->IsJSArray() || cell != NULL) return heap()->undefined_value(); 1452 if (!object->IsJSArray() || !cell.is_null()) return Handle<Code>::null();
1769 1453
1770 Label miss; 1454 Label miss;
1771 1455
1772 GenerateNameCheck(Handle<String>(name), &miss); 1456 GenerateNameCheck(name, &miss);
1773 1457
1774 Register receiver = a1; 1458 Register receiver = a1;
1775 1459
1776 // Get the receiver from the stack. 1460 // Get the receiver from the stack.
1777 const int argc = arguments().immediate(); 1461 const int argc = arguments().immediate();
1778 __ lw(receiver, MemOperand(sp, argc * kPointerSize)); 1462 __ lw(receiver, MemOperand(sp, argc * kPointerSize));
1779 1463
1780 // Check that the receiver isn't a smi. 1464 // Check that the receiver isn't a smi.
1781 __ JumpIfSmi(receiver, &miss); 1465 __ JumpIfSmi(receiver, &miss);
1782 1466
1783 // Check that the maps haven't changed. 1467 // Check that the maps haven't changed.
1784 CheckPrototypes(JSObject::cast(object), receiver, 1468 CheckPrototypes(Handle<JSObject>::cast(object), receiver, holder, a3, v0, t0,
1785 holder, a3, v0, t0, name, &miss); 1469 name, &miss);
1786 1470
1787 if (argc == 0) { 1471 if (argc == 0) {
1788 // Nothing to do, just return the length. 1472 // Nothing to do, just return the length.
1789 __ lw(v0, FieldMemOperand(receiver, JSArray::kLengthOffset)); 1473 __ lw(v0, FieldMemOperand(receiver, JSArray::kLengthOffset));
1790 __ Drop(argc + 1); 1474 __ Drop(argc + 1);
1791 __ Ret(); 1475 __ Ret();
1792 } else { 1476 } else {
1793 Label call_builtin; 1477 Label call_builtin;
1794
1795 Register elements = a3; 1478 Register elements = a3;
1796 Register end_elements = t1; 1479 Register end_elements = t1;
1797
1798 // Get the elements array of the object. 1480 // Get the elements array of the object.
1799 __ lw(elements, FieldMemOperand(receiver, JSArray::kElementsOffset)); 1481 __ lw(elements, FieldMemOperand(receiver, JSArray::kElementsOffset));
1800 1482
1801 // Check that the elements are in fast mode and writable. 1483 // Check that the elements are in fast mode and writable.
1802 __ CheckMap(elements, 1484 __ CheckMap(elements,
1803 v0, 1485 v0,
1804 Heap::kFixedArrayMapRootIndex, 1486 Heap::kFixedArrayMapRootIndex,
1805 &call_builtin, 1487 &call_builtin,
1806 DONT_DO_SMI_CHECK); 1488 DONT_DO_SMI_CHECK);
1807 1489
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
1928 } 1610 }
1929 __ bind(&call_builtin); 1611 __ bind(&call_builtin);
1930 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPush, 1612 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPush,
1931 masm()->isolate()), 1613 masm()->isolate()),
1932 argc + 1, 1614 argc + 1,
1933 1); 1615 1);
1934 } 1616 }
1935 1617
1936 // Handle call cache miss. 1618 // Handle call cache miss.
1937 __ bind(&miss); 1619 __ bind(&miss);
1938 MaybeObject* maybe_result = TryGenerateMissBranch(); 1620 GenerateMissBranch();
1939 if (maybe_result->IsFailure()) return maybe_result;
1940 1621
1941 // Return the generated code. 1622 // Return the generated code.
1942 return TryGetCode(function); 1623 return GetCode(function);
1943 } 1624 }
1944 1625
1945 1626
1946 MaybeObject* CallStubCompiler::CompileArrayPopCall(Object* object, 1627 Handle<Code> CallStubCompiler::CompileArrayPopCall(
1947 JSObject* holder, 1628 Handle<Object> object,
1948 JSGlobalPropertyCell* cell, 1629 Handle<JSObject> holder,
1949 JSFunction* function, 1630 Handle<JSGlobalPropertyCell> cell,
1950 String* name) { 1631 Handle<JSFunction> function,
1632 Handle<String> name) {
1951 // ----------- S t a t e ------------- 1633 // ----------- S t a t e -------------
1952 // -- a2 : name 1634 // -- a2 : name
1953 // -- ra : return address 1635 // -- ra : return address
1954 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) 1636 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based)
1955 // -- ... 1637 // -- ...
1956 // -- sp[argc * 4] : receiver 1638 // -- sp[argc * 4] : receiver
1957 // ----------------------------------- 1639 // -----------------------------------
1958 1640
1959 // If object is not an array, bail out to regular call. 1641 // If object is not an array, bail out to regular call.
1960 if (!object->IsJSArray() || cell != NULL) return heap()->undefined_value(); 1642 if (!object->IsJSArray() || !cell.is_null()) return Handle<Code>::null();
1961 1643
1962 Label miss, return_undefined, call_builtin; 1644 Label miss, return_undefined, call_builtin;
1963
1964 Register receiver = a1; 1645 Register receiver = a1;
1965 Register elements = a3; 1646 Register elements = a3;
1966 1647 GenerateNameCheck(name, &miss);
1967 GenerateNameCheck(Handle<String>(name), &miss);
1968 1648
1969 // Get the receiver from the stack. 1649 // Get the receiver from the stack.
1970 const int argc = arguments().immediate(); 1650 const int argc = arguments().immediate();
1971 __ lw(receiver, MemOperand(sp, argc * kPointerSize)); 1651 __ lw(receiver, MemOperand(sp, argc * kPointerSize));
1972
1973 // Check that the receiver isn't a smi. 1652 // Check that the receiver isn't a smi.
1974 __ JumpIfSmi(receiver, &miss); 1653 __ JumpIfSmi(receiver, &miss);
1975 1654
1976 // Check that the maps haven't changed. 1655 // Check that the maps haven't changed.
1977 CheckPrototypes(JSObject::cast(object), 1656 CheckPrototypes(Handle<JSObject>::cast(object), receiver, holder, elements,
1978 receiver, holder, elements, t0, v0, name, &miss); 1657 t0, v0, name, &miss);
1979 1658
1980 // Get the elements array of the object. 1659 // Get the elements array of the object.
1981 __ lw(elements, FieldMemOperand(receiver, JSArray::kElementsOffset)); 1660 __ lw(elements, FieldMemOperand(receiver, JSArray::kElementsOffset));
1982 1661
1983 // Check that the elements are in fast mode and writable. 1662 // Check that the elements are in fast mode and writable.
1984 __ CheckMap(elements, 1663 __ CheckMap(elements,
1985 v0, 1664 v0,
1986 Heap::kFixedArrayMapRootIndex, 1665 Heap::kFixedArrayMapRootIndex,
1987 &call_builtin, 1666 &call_builtin,
1988 DONT_DO_SMI_CHECK); 1667 DONT_DO_SMI_CHECK);
(...skipping 28 matching lines...) Expand all
2017 __ Ret(); 1696 __ Ret();
2018 1697
2019 __ bind(&call_builtin); 1698 __ bind(&call_builtin);
2020 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPop, 1699 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPop,
2021 masm()->isolate()), 1700 masm()->isolate()),
2022 argc + 1, 1701 argc + 1,
2023 1); 1702 1);
2024 1703
2025 // Handle call cache miss. 1704 // Handle call cache miss.
2026 __ bind(&miss); 1705 __ bind(&miss);
2027 MaybeObject* maybe_result = TryGenerateMissBranch(); 1706 GenerateMissBranch();
2028 if (maybe_result->IsFailure()) return maybe_result;
2029 1707
2030 // Return the generated code. 1708 // Return the generated code.
2031 return TryGetCode(function); 1709 return GetCode(function);
2032 } 1710 }
2033 1711
2034 1712
2035 MaybeObject* CallStubCompiler::CompileStringCharCodeAtCall( 1713 Handle<Code> CallStubCompiler::CompileStringCharCodeAtCall(
2036 Object* object, 1714 Handle<Object> object,
2037 JSObject* holder, 1715 Handle<JSObject> holder,
2038 JSGlobalPropertyCell* cell, 1716 Handle<JSGlobalPropertyCell> cell,
2039 JSFunction* function, 1717 Handle<JSFunction> function,
2040 String* name) { 1718 Handle<String> name) {
2041 // ----------- S t a t e ------------- 1719 // ----------- S t a t e -------------
2042 // -- a2 : function name 1720 // -- a2 : function name
2043 // -- ra : return address 1721 // -- ra : return address
2044 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) 1722 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based)
2045 // -- ... 1723 // -- ...
2046 // -- sp[argc * 4] : receiver 1724 // -- sp[argc * 4] : receiver
2047 // ----------------------------------- 1725 // -----------------------------------
2048 1726
2049 // If object is not a string, bail out to regular call. 1727 // If object is not a string, bail out to regular call.
2050 if (!object->IsString() || cell != NULL) return heap()->undefined_value(); 1728 if (!object->IsString() || !cell.is_null()) return Handle<Code>::null();
2051 1729
2052 const int argc = arguments().immediate(); 1730 const int argc = arguments().immediate();
2053
2054 Label miss; 1731 Label miss;
2055 Label name_miss; 1732 Label name_miss;
2056 Label index_out_of_range; 1733 Label index_out_of_range;
2057 1734
2058 Label* index_out_of_range_label = &index_out_of_range; 1735 Label* index_out_of_range_label = &index_out_of_range;
2059 1736
2060 if (kind_ == Code::CALL_IC && 1737 if (kind_ == Code::CALL_IC &&
2061 (CallICBase::StringStubState::decode(extra_state_) == 1738 (CallICBase::StringStubState::decode(extra_state_) ==
2062 DEFAULT_STRING_STUB)) { 1739 DEFAULT_STRING_STUB)) {
2063 index_out_of_range_label = &miss; 1740 index_out_of_range_label = &miss;
2064 } 1741 }
2065 1742
2066 GenerateNameCheck(Handle<String>(name), &name_miss); 1743 GenerateNameCheck(name, &name_miss);
2067 1744
2068 // Check that the maps starting from the prototype haven't changed. 1745 // Check that the maps starting from the prototype haven't changed.
2069 GenerateDirectLoadGlobalFunctionPrototype(masm(), 1746 GenerateDirectLoadGlobalFunctionPrototype(masm(),
2070 Context::STRING_FUNCTION_INDEX, 1747 Context::STRING_FUNCTION_INDEX,
2071 v0, 1748 v0,
2072 &miss); 1749 &miss);
2073 ASSERT(object != holder); 1750 ASSERT(!object.is_identical_to(holder));
2074 CheckPrototypes(JSObject::cast(object->GetPrototype()), v0, holder, 1751 CheckPrototypes(Handle<JSObject>(JSObject::cast(object->GetPrototype())),
2075 a1, a3, t0, name, &miss); 1752 v0, holder, a1, a3, t0, name, &miss);
2076 1753
2077 Register receiver = a1; 1754 Register receiver = a1;
2078 Register index = t1; 1755 Register index = t1;
2079 Register scratch = a3; 1756 Register scratch = a3;
2080 Register result = v0; 1757 Register result = v0;
2081 __ lw(receiver, MemOperand(sp, argc * kPointerSize)); 1758 __ lw(receiver, MemOperand(sp, argc * kPointerSize));
2082 if (argc > 0) { 1759 if (argc > 0) {
2083 __ lw(index, MemOperand(sp, (argc - 1) * kPointerSize)); 1760 __ lw(index, MemOperand(sp, (argc - 1) * kPointerSize));
2084 } else { 1761 } else {
2085 __ LoadRoot(index, Heap::kUndefinedValueRootIndex); 1762 __ LoadRoot(index, Heap::kUndefinedValueRootIndex);
2086 } 1763 }
2087 1764
2088 StringCharCodeAtGenerator char_code_at_generator(receiver, 1765 StringCharCodeAtGenerator generator(receiver,
2089 index, 1766 index,
2090 scratch, 1767 scratch,
2091 result, 1768 result,
2092 &miss, // When not a string. 1769 &miss, // When not a string.
2093 &miss, // When not a number. 1770 &miss, // When not a number.
2094 index_out_of_range_label, 1771 index_out_of_range_label,
2095 STRING_INDEX_IS_NUMBER); 1772 STRING_INDEX_IS_NUMBER);
2096 char_code_at_generator.GenerateFast(masm()); 1773 generator.GenerateFast(masm());
2097 __ Drop(argc + 1); 1774 __ Drop(argc + 1);
2098 __ Ret(); 1775 __ Ret();
2099 1776
2100 StubRuntimeCallHelper call_helper; 1777 StubRuntimeCallHelper call_helper;
2101 char_code_at_generator.GenerateSlow(masm(), call_helper); 1778 generator.GenerateSlow(masm(), call_helper);
2102 1779
2103 if (index_out_of_range.is_linked()) { 1780 if (index_out_of_range.is_linked()) {
2104 __ bind(&index_out_of_range); 1781 __ bind(&index_out_of_range);
2105 __ LoadRoot(v0, Heap::kNanValueRootIndex); 1782 __ LoadRoot(v0, Heap::kNanValueRootIndex);
2106 __ Drop(argc + 1); 1783 __ Drop(argc + 1);
2107 __ Ret(); 1784 __ Ret();
2108 } 1785 }
2109 1786
2110 __ bind(&miss); 1787 __ bind(&miss);
2111 // Restore function name in a2. 1788 // Restore function name in a2.
2112 __ li(a2, Handle<String>(name)); 1789 __ li(a2, name);
2113 __ bind(&name_miss); 1790 __ bind(&name_miss);
2114 MaybeObject* maybe_result = TryGenerateMissBranch(); 1791 GenerateMissBranch();
2115 if (maybe_result->IsFailure()) return maybe_result;
2116 1792
2117 // Return the generated code. 1793 // Return the generated code.
2118 return TryGetCode(function); 1794 return GetCode(function);
2119 } 1795 }
2120 1796
2121 1797
2122 MaybeObject* CallStubCompiler::CompileStringCharAtCall( 1798 Handle<Code> CallStubCompiler::CompileStringCharAtCall(
2123 Object* object, 1799 Handle<Object> object,
2124 JSObject* holder, 1800 Handle<JSObject> holder,
2125 JSGlobalPropertyCell* cell, 1801 Handle<JSGlobalPropertyCell> cell,
2126 JSFunction* function, 1802 Handle<JSFunction> function,
2127 String* name) { 1803 Handle<String> name) {
2128 // ----------- S t a t e ------------- 1804 // ----------- S t a t e -------------
2129 // -- a2 : function name 1805 // -- a2 : function name
2130 // -- ra : return address 1806 // -- ra : return address
2131 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) 1807 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based)
2132 // -- ... 1808 // -- ...
2133 // -- sp[argc * 4] : receiver 1809 // -- sp[argc * 4] : receiver
2134 // ----------------------------------- 1810 // -----------------------------------
2135 1811
2136 // If object is not a string, bail out to regular call. 1812 // If object is not a string, bail out to regular call.
2137 if (!object->IsString() || cell != NULL) return heap()->undefined_value(); 1813 if (!object->IsString() || !cell.is_null()) return Handle<Code>::null();
2138 1814
2139 const int argc = arguments().immediate(); 1815 const int argc = arguments().immediate();
2140
2141 Label miss; 1816 Label miss;
2142 Label name_miss; 1817 Label name_miss;
2143 Label index_out_of_range; 1818 Label index_out_of_range;
2144 Label* index_out_of_range_label = &index_out_of_range; 1819 Label* index_out_of_range_label = &index_out_of_range;
2145
2146 if (kind_ == Code::CALL_IC && 1820 if (kind_ == Code::CALL_IC &&
2147 (CallICBase::StringStubState::decode(extra_state_) == 1821 (CallICBase::StringStubState::decode(extra_state_) ==
2148 DEFAULT_STRING_STUB)) { 1822 DEFAULT_STRING_STUB)) {
2149 index_out_of_range_label = &miss; 1823 index_out_of_range_label = &miss;
2150 } 1824 }
2151 1825 GenerateNameCheck(name, &name_miss);
2152 GenerateNameCheck(Handle<String>(name), &name_miss);
2153 1826
2154 // Check that the maps starting from the prototype haven't changed. 1827 // Check that the maps starting from the prototype haven't changed.
2155 GenerateDirectLoadGlobalFunctionPrototype(masm(), 1828 GenerateDirectLoadGlobalFunctionPrototype(masm(),
2156 Context::STRING_FUNCTION_INDEX, 1829 Context::STRING_FUNCTION_INDEX,
2157 v0, 1830 v0,
2158 &miss); 1831 &miss);
2159 ASSERT(object != holder); 1832 ASSERT(!object.is_identical_to(holder));
2160 CheckPrototypes(JSObject::cast(object->GetPrototype()), v0, holder, 1833 CheckPrototypes(Handle<JSObject>(JSObject::cast(object->GetPrototype())),
2161 a1, a3, t0, name, &miss); 1834 v0, holder, a1, a3, t0, name, &miss);
2162 1835
2163 Register receiver = v0; 1836 Register receiver = v0;
2164 Register index = t1; 1837 Register index = t1;
2165 Register scratch1 = a1; 1838 Register scratch1 = a1;
2166 Register scratch2 = a3; 1839 Register scratch2 = a3;
2167 Register result = v0; 1840 Register result = v0;
2168 __ lw(receiver, MemOperand(sp, argc * kPointerSize)); 1841 __ lw(receiver, MemOperand(sp, argc * kPointerSize));
2169 if (argc > 0) { 1842 if (argc > 0) {
2170 __ lw(index, MemOperand(sp, (argc - 1) * kPointerSize)); 1843 __ lw(index, MemOperand(sp, (argc - 1) * kPointerSize));
2171 } else { 1844 } else {
2172 __ LoadRoot(index, Heap::kUndefinedValueRootIndex); 1845 __ LoadRoot(index, Heap::kUndefinedValueRootIndex);
2173 } 1846 }
2174 1847
2175 StringCharAtGenerator char_at_generator(receiver, 1848 StringCharAtGenerator generator(receiver,
2176 index, 1849 index,
2177 scratch1, 1850 scratch1,
2178 scratch2, 1851 scratch2,
2179 result, 1852 result,
2180 &miss, // When not a string. 1853 &miss, // When not a string.
2181 &miss, // When not a number. 1854 &miss, // When not a number.
2182 index_out_of_range_label, 1855 index_out_of_range_label,
2183 STRING_INDEX_IS_NUMBER); 1856 STRING_INDEX_IS_NUMBER);
2184 char_at_generator.GenerateFast(masm()); 1857 generator.GenerateFast(masm());
2185 __ Drop(argc + 1); 1858 __ Drop(argc + 1);
2186 __ Ret(); 1859 __ Ret();
2187 1860
2188 StubRuntimeCallHelper call_helper; 1861 StubRuntimeCallHelper call_helper;
2189 char_at_generator.GenerateSlow(masm(), call_helper); 1862 generator.GenerateSlow(masm(), call_helper);
2190 1863
2191 if (index_out_of_range.is_linked()) { 1864 if (index_out_of_range.is_linked()) {
2192 __ bind(&index_out_of_range); 1865 __ bind(&index_out_of_range);
2193 __ LoadRoot(v0, Heap::kEmptyStringRootIndex); 1866 __ LoadRoot(v0, Heap::kEmptyStringRootIndex);
2194 __ Drop(argc + 1); 1867 __ Drop(argc + 1);
2195 __ Ret(); 1868 __ Ret();
2196 } 1869 }
2197 1870
2198 __ bind(&miss); 1871 __ bind(&miss);
2199 // Restore function name in a2. 1872 // Restore function name in a2.
2200 __ li(a2, Handle<String>(name)); 1873 __ li(a2, name);
2201 __ bind(&name_miss); 1874 __ bind(&name_miss);
2202 MaybeObject* maybe_result = TryGenerateMissBranch(); 1875 GenerateMissBranch();
2203 if (maybe_result->IsFailure()) return maybe_result;
2204 1876
2205 // Return the generated code. 1877 // Return the generated code.
2206 return TryGetCode(function); 1878 return GetCode(function);
2207 } 1879 }
2208 1880
2209 1881
2210 MaybeObject* CallStubCompiler::CompileStringFromCharCodeCall( 1882 Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall(
2211 Object* object, 1883 Handle<Object> object,
2212 JSObject* holder, 1884 Handle<JSObject> holder,
2213 JSGlobalPropertyCell* cell, 1885 Handle<JSGlobalPropertyCell> cell,
2214 JSFunction* function, 1886 Handle<JSFunction> function,
2215 String* name) { 1887 Handle<String> name) {
2216 // ----------- S t a t e ------------- 1888 // ----------- S t a t e -------------
2217 // -- a2 : function name 1889 // -- a2 : function name
2218 // -- ra : return address 1890 // -- ra : return address
2219 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) 1891 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based)
2220 // -- ... 1892 // -- ...
2221 // -- sp[argc * 4] : receiver 1893 // -- sp[argc * 4] : receiver
2222 // ----------------------------------- 1894 // -----------------------------------
2223 1895
2224 const int argc = arguments().immediate(); 1896 const int argc = arguments().immediate();
2225 1897
2226 // If the object is not a JSObject or we got an unexpected number of 1898 // If the object is not a JSObject or we got an unexpected number of
2227 // arguments, bail out to the regular call. 1899 // arguments, bail out to the regular call.
2228 if (!object->IsJSObject() || argc != 1) return heap()->undefined_value(); 1900 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null();
2229 1901
2230 Label miss; 1902 Label miss;
2231 GenerateNameCheck(Handle<String>(name), &miss); 1903 GenerateNameCheck(name, &miss);
2232 1904
2233 if (cell == NULL) { 1905 if (cell.is_null()) {
2234 __ lw(a1, MemOperand(sp, 1 * kPointerSize)); 1906 __ lw(a1, MemOperand(sp, 1 * kPointerSize));
2235 1907
2236 STATIC_ASSERT(kSmiTag == 0); 1908 STATIC_ASSERT(kSmiTag == 0);
2237 __ JumpIfSmi(a1, &miss); 1909 __ JumpIfSmi(a1, &miss);
2238 1910
2239 CheckPrototypes(JSObject::cast(object), a1, holder, v0, a3, t0, name, 1911 CheckPrototypes(Handle<JSObject>::cast(object), a1, holder, v0, a3, t0,
2240 &miss); 1912 name, &miss);
2241 } else { 1913 } else {
2242 ASSERT(cell->value() == function); 1914 ASSERT(cell->value() == *function);
2243 GenerateGlobalReceiverCheck(JSObject::cast(object), holder, name, &miss); 1915 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name,
1916 &miss);
2244 GenerateLoadFunctionFromCell(cell, function, &miss); 1917 GenerateLoadFunctionFromCell(cell, function, &miss);
2245 } 1918 }
2246 1919
2247 // Load the char code argument. 1920 // Load the char code argument.
2248 Register code = a1; 1921 Register code = a1;
2249 __ lw(code, MemOperand(sp, 0 * kPointerSize)); 1922 __ lw(code, MemOperand(sp, 0 * kPointerSize));
2250 1923
2251 // Check the code is a smi. 1924 // Check the code is a smi.
2252 Label slow; 1925 Label slow;
2253 STATIC_ASSERT(kSmiTag == 0); 1926 STATIC_ASSERT(kSmiTag == 0);
2254 __ JumpIfNotSmi(code, &slow); 1927 __ JumpIfNotSmi(code, &slow);
2255 1928
2256 // Convert the smi code to uint16. 1929 // Convert the smi code to uint16.
2257 __ And(code, code, Operand(Smi::FromInt(0xffff))); 1930 __ And(code, code, Operand(Smi::FromInt(0xffff)));
2258 1931
2259 StringCharFromCodeGenerator char_from_code_generator(code, v0); 1932 StringCharFromCodeGenerator generator(code, v0);
2260 char_from_code_generator.GenerateFast(masm()); 1933 generator.GenerateFast(masm());
2261 __ Drop(argc + 1); 1934 __ Drop(argc + 1);
2262 __ Ret(); 1935 __ Ret();
2263 1936
2264 StubRuntimeCallHelper call_helper; 1937 StubRuntimeCallHelper call_helper;
2265 char_from_code_generator.GenerateSlow(masm(), call_helper); 1938 generator.GenerateSlow(masm(), call_helper);
2266 1939
2267 // Tail call the full function. We do not have to patch the receiver 1940 // Tail call the full function. We do not have to patch the receiver
2268 // because the function makes no use of it. 1941 // because the function makes no use of it.
2269 __ bind(&slow); 1942 __ bind(&slow);
2270 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, CALL_AS_METHOD); 1943 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, CALL_AS_METHOD);
2271 1944
2272 __ bind(&miss); 1945 __ bind(&miss);
2273 // a2: function name. 1946 // a2: function name.
2274 MaybeObject* maybe_result = TryGenerateMissBranch(); 1947 GenerateMissBranch();
2275 if (maybe_result->IsFailure()) return maybe_result;
2276 1948
2277 // Return the generated code. 1949 // Return the generated code.
2278 return (cell == NULL) ? TryGetCode(function) : TryGetCode(NORMAL, name); 1950 return cell.is_null() ? GetCode(function) : GetCode(NORMAL, name);
2279 } 1951 }
2280 1952
2281 1953
2282 MaybeObject* CallStubCompiler::CompileMathFloorCall(Object* object, 1954 Handle<Code> CallStubCompiler::CompileMathFloorCall(
2283 JSObject* holder, 1955 Handle<Object> object,
2284 JSGlobalPropertyCell* cell, 1956 Handle<JSObject> holder,
2285 JSFunction* function, 1957 Handle<JSGlobalPropertyCell> cell,
2286 String* name) { 1958 Handle<JSFunction> function,
1959 Handle<String> name) {
2287 // ----------- S t a t e ------------- 1960 // ----------- S t a t e -------------
2288 // -- a2 : function name 1961 // -- a2 : function name
2289 // -- ra : return address 1962 // -- ra : return address
2290 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) 1963 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based)
2291 // -- ... 1964 // -- ...
2292 // -- sp[argc * 4] : receiver 1965 // -- sp[argc * 4] : receiver
2293 // ----------------------------------- 1966 // -----------------------------------
2294 1967
2295 if (!CpuFeatures::IsSupported(FPU)) 1968 if (!CpuFeatures::IsSupported(FPU)) {
2296 return heap()->undefined_value(); 1969 return Handle<Code>::null();
1970 }
1971
2297 CpuFeatures::Scope scope_fpu(FPU); 1972 CpuFeatures::Scope scope_fpu(FPU);
2298
2299 const int argc = arguments().immediate(); 1973 const int argc = arguments().immediate();
2300
2301 // If the object is not a JSObject or we got an unexpected number of 1974 // If the object is not a JSObject or we got an unexpected number of
2302 // arguments, bail out to the regular call. 1975 // arguments, bail out to the regular call.
2303 if (!object->IsJSObject() || argc != 1) return heap()->undefined_value(); 1976 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null();
2304 1977
2305 Label miss, slow; 1978 Label miss, slow;
2306 GenerateNameCheck(Handle<String>(name), &miss); 1979 GenerateNameCheck(name, &miss);
2307 1980
2308 if (cell == NULL) { 1981 if (cell.is_null()) {
2309 __ lw(a1, MemOperand(sp, 1 * kPointerSize)); 1982 __ lw(a1, MemOperand(sp, 1 * kPointerSize));
2310
2311 STATIC_ASSERT(kSmiTag == 0); 1983 STATIC_ASSERT(kSmiTag == 0);
2312 __ JumpIfSmi(a1, &miss); 1984 __ JumpIfSmi(a1, &miss);
2313 1985 CheckPrototypes(Handle<JSObject>::cast(object), a1, holder, a0, a3, t0,
2314 CheckPrototypes(JSObject::cast(object), a1, holder, a0, a3, t0, name, 1986 name, &miss);
2315 &miss);
2316 } else { 1987 } else {
2317 ASSERT(cell->value() == function); 1988 ASSERT(cell->value() == *function);
2318 GenerateGlobalReceiverCheck(JSObject::cast(object), holder, name, &miss); 1989 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name,
1990 &miss);
2319 GenerateLoadFunctionFromCell(cell, function, &miss); 1991 GenerateLoadFunctionFromCell(cell, function, &miss);
2320 } 1992 }
2321 1993
2322 // Load the (only) argument into v0. 1994 // Load the (only) argument into v0.
2323 __ lw(v0, MemOperand(sp, 0 * kPointerSize)); 1995 __ lw(v0, MemOperand(sp, 0 * kPointerSize));
2324 1996
2325 // If the argument is a smi, just return. 1997 // If the argument is a smi, just return.
2326 STATIC_ASSERT(kSmiTag == 0); 1998 STATIC_ASSERT(kSmiTag == 0);
2327 __ And(t0, v0, Operand(kSmiTagMask)); 1999 __ And(t0, v0, Operand(kSmiTagMask));
2328 __ Drop(argc + 1, eq, t0, Operand(zero_reg)); 2000 __ Drop(argc + 1, eq, t0, Operand(zero_reg));
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
2398 // Restore FCSR and fall to slow case. 2070 // Restore FCSR and fall to slow case.
2399 __ ctc1(a3, FCSR); 2071 __ ctc1(a3, FCSR);
2400 2072
2401 __ bind(&slow); 2073 __ bind(&slow);
2402 // Tail call the full function. We do not have to patch the receiver 2074 // Tail call the full function. We do not have to patch the receiver
2403 // because the function makes no use of it. 2075 // because the function makes no use of it.
2404 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, CALL_AS_METHOD); 2076 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, CALL_AS_METHOD);
2405 2077
2406 __ bind(&miss); 2078 __ bind(&miss);
2407 // a2: function name. 2079 // a2: function name.
2408 MaybeObject* obj = TryGenerateMissBranch(); 2080 GenerateMissBranch();
2409 if (obj->IsFailure()) return obj;
2410 2081
2411 // Return the generated code. 2082 // Return the generated code.
2412 return (cell == NULL) ? TryGetCode(function) : TryGetCode(NORMAL, name); 2083 return cell.is_null() ? GetCode(function) : GetCode(NORMAL, name);
2413 } 2084 }
2414 2085
2415 2086
2416 MaybeObject* CallStubCompiler::CompileMathAbsCall(Object* object, 2087 Handle<Code> CallStubCompiler::CompileMathAbsCall(
2417 JSObject* holder, 2088 Handle<Object> object,
2418 JSGlobalPropertyCell* cell, 2089 Handle<JSObject> holder,
2419 JSFunction* function, 2090 Handle<JSGlobalPropertyCell> cell,
2420 String* name) { 2091 Handle<JSFunction> function,
2092 Handle<String> name) {
2421 // ----------- S t a t e ------------- 2093 // ----------- S t a t e -------------
2422 // -- a2 : function name 2094 // -- a2 : function name
2423 // -- ra : return address 2095 // -- ra : return address
2424 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) 2096 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based)
2425 // -- ... 2097 // -- ...
2426 // -- sp[argc * 4] : receiver 2098 // -- sp[argc * 4] : receiver
2427 // ----------------------------------- 2099 // -----------------------------------
2428 2100
2429 const int argc = arguments().immediate(); 2101 const int argc = arguments().immediate();
2430
2431 // If the object is not a JSObject or we got an unexpected number of 2102 // If the object is not a JSObject or we got an unexpected number of
2432 // arguments, bail out to the regular call. 2103 // arguments, bail out to the regular call.
2433 if (!object->IsJSObject() || argc != 1) return heap()->undefined_value(); 2104 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null();
2434 2105
2435 Label miss; 2106 Label miss;
2436 GenerateNameCheck(Handle<String>(name), &miss);
2437 2107
2438 if (cell == NULL) { 2108 GenerateNameCheck(name, &miss);
2109 if (cell.is_null()) {
2439 __ lw(a1, MemOperand(sp, 1 * kPointerSize)); 2110 __ lw(a1, MemOperand(sp, 1 * kPointerSize));
2440
2441 STATIC_ASSERT(kSmiTag == 0); 2111 STATIC_ASSERT(kSmiTag == 0);
2442 __ JumpIfSmi(a1, &miss); 2112 __ JumpIfSmi(a1, &miss);
2443 2113 CheckPrototypes(Handle<JSObject>::cast(object), a1, holder, v0, a3, t0,
2444 CheckPrototypes(JSObject::cast(object), a1, holder, v0, a3, t0, name, 2114 name, &miss);
2445 &miss);
2446 } else { 2115 } else {
2447 ASSERT(cell->value() == function); 2116 ASSERT(cell->value() == *function);
2448 GenerateGlobalReceiverCheck(JSObject::cast(object), holder, name, &miss); 2117 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name,
2118 &miss);
2449 GenerateLoadFunctionFromCell(cell, function, &miss); 2119 GenerateLoadFunctionFromCell(cell, function, &miss);
2450 } 2120 }
2451 2121
2452 // Load the (only) argument into v0. 2122 // Load the (only) argument into v0.
2453 __ lw(v0, MemOperand(sp, 0 * kPointerSize)); 2123 __ lw(v0, MemOperand(sp, 0 * kPointerSize));
2454 2124
2455 // Check if the argument is a smi. 2125 // Check if the argument is a smi.
2456 Label not_smi; 2126 Label not_smi;
2457 STATIC_ASSERT(kSmiTag == 0); 2127 STATIC_ASSERT(kSmiTag == 0);
2458 __ JumpIfNotSmi(v0, &not_smi); 2128 __ JumpIfNotSmi(v0, &not_smi);
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
2500 __ Drop(argc + 1); 2170 __ Drop(argc + 1);
2501 __ Ret(); 2171 __ Ret();
2502 2172
2503 // Tail call the full function. We do not have to patch the receiver 2173 // Tail call the full function. We do not have to patch the receiver
2504 // because the function makes no use of it. 2174 // because the function makes no use of it.
2505 __ bind(&slow); 2175 __ bind(&slow);
2506 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, CALL_AS_METHOD); 2176 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, CALL_AS_METHOD);
2507 2177
2508 __ bind(&miss); 2178 __ bind(&miss);
2509 // a2: function name. 2179 // a2: function name.
2510 MaybeObject* maybe_result = TryGenerateMissBranch(); 2180 GenerateMissBranch();
2511 if (maybe_result->IsFailure()) return maybe_result;
2512 2181
2513 // Return the generated code. 2182 // Return the generated code.
2514 return (cell == NULL) ? TryGetCode(function) : TryGetCode(NORMAL, name); 2183 return cell.is_null() ? GetCode(function) : GetCode(NORMAL, name);
2515 } 2184 }
2516 2185
2517 2186
2518 MaybeObject* CallStubCompiler::CompileFastApiCall( 2187 Handle<Code> CallStubCompiler::CompileFastApiCall(
2519 const CallOptimization& optimization, 2188 const CallOptimization& optimization,
2520 Object* object, 2189 Handle<Object> object,
2521 JSObject* holder, 2190 Handle<JSObject> holder,
2522 JSGlobalPropertyCell* cell, 2191 Handle<JSGlobalPropertyCell> cell,
2523 JSFunction* function, 2192 Handle<JSFunction> function,
2524 String* name) { 2193 Handle<String> name) {
2525 2194
2526 Counters* counters = isolate()->counters(); 2195 Counters* counters = isolate()->counters();
2527 2196
2528 ASSERT(optimization.is_simple_api_call()); 2197 ASSERT(optimization.is_simple_api_call());
2529 // Bail out if object is a global object as we don't want to 2198 // Bail out if object is a global object as we don't want to
2530 // repatch it to global receiver. 2199 // repatch it to global receiver.
2531 if (object->IsGlobalObject()) return heap()->undefined_value(); 2200 if (object->IsGlobalObject()) return Handle<Code>::null();
2532 if (cell != NULL) return heap()->undefined_value(); 2201 if (!cell.is_null()) return Handle<Code>::null();
2533 if (!object->IsJSObject()) return heap()->undefined_value(); 2202 if (!object->IsJSObject()) return Handle<Code>::null();
2534 int depth = optimization.GetPrototypeDepthOfExpectedType( 2203 int depth = optimization.GetPrototypeDepthOfExpectedType(
2535 JSObject::cast(object), holder); 2204 Handle<JSObject>::cast(object), holder);
2536 if (depth == kInvalidProtoDepth) return heap()->undefined_value(); 2205 if (depth == kInvalidProtoDepth) return Handle<Code>::null();
2537 2206
2538 Label miss, miss_before_stack_reserved; 2207 Label miss, miss_before_stack_reserved;
2539 2208
2540 GenerateNameCheck(Handle<String>(name), &miss_before_stack_reserved); 2209 GenerateNameCheck(name, &miss_before_stack_reserved);
2541 2210
2542 // Get the receiver from the stack. 2211 // Get the receiver from the stack.
2543 const int argc = arguments().immediate(); 2212 const int argc = arguments().immediate();
2544 __ lw(a1, MemOperand(sp, argc * kPointerSize)); 2213 __ lw(a1, MemOperand(sp, argc * kPointerSize));
2545 2214
2546 // Check that the receiver isn't a smi. 2215 // Check that the receiver isn't a smi.
2547 __ JumpIfSmi(a1, &miss_before_stack_reserved); 2216 __ JumpIfSmi(a1, &miss_before_stack_reserved);
2548 2217
2549 __ IncrementCounter(counters->call_const(), 1, a0, a3); 2218 __ IncrementCounter(counters->call_const(), 1, a0, a3);
2550 __ IncrementCounter(counters->call_const_fast_api(), 1, a0, a3); 2219 __ IncrementCounter(counters->call_const_fast_api(), 1, a0, a3);
2551 2220
2552 ReserveSpaceForFastApiCall(masm(), a0); 2221 ReserveSpaceForFastApiCall(masm(), a0);
2553 2222
2554 // Check that the maps haven't changed and find a Holder as a side effect. 2223 // Check that the maps haven't changed and find a Holder as a side effect.
2555 CheckPrototypes(JSObject::cast(object), a1, holder, a0, a3, t0, name, 2224 CheckPrototypes(Handle<JSObject>::cast(object), a1, holder, a0, a3, t0, name,
2556 depth, &miss); 2225 depth, &miss);
2557 2226
2558 MaybeObject* result = GenerateFastApiDirectCall(masm(), optimization, argc); 2227 GenerateFastApiDirectCall(masm(), optimization, argc);
2559 if (result->IsFailure()) return result;
2560 2228
2561 __ bind(&miss); 2229 __ bind(&miss);
2562 FreeSpaceForFastApiCall(masm()); 2230 FreeSpaceForFastApiCall(masm());
2563 2231
2564 __ bind(&miss_before_stack_reserved); 2232 __ bind(&miss_before_stack_reserved);
2565 MaybeObject* maybe_result = TryGenerateMissBranch(); 2233 GenerateMissBranch();
2566 if (maybe_result->IsFailure()) return maybe_result;
2567 2234
2568 // Return the generated code. 2235 // Return the generated code.
2569 return TryGetCode(function); 2236 return GetCode(function);
2570 } 2237 }
2571 2238
2572 2239
2573 MaybeObject* CallStubCompiler::CompileCallConstant(Object* object, 2240 Handle<Code> CallStubCompiler::CompileCallConstant(Handle<Object> object,
2574 JSObject* holder, 2241 Handle<JSObject> holder,
2575 JSFunction* function, 2242 Handle<JSFunction> function,
2576 String* name, 2243 Handle<String> name,
2577 CheckType check) { 2244 CheckType check) {
2578 // ----------- S t a t e ------------- 2245 // ----------- S t a t e -------------
2579 // -- a2 : name 2246 // -- a2 : name
2580 // -- ra : return address 2247 // -- ra : return address
2581 // ----------------------------------- 2248 // -----------------------------------
2582 if (HasCustomCallGenerator(function)) { 2249 if (HasCustomCallGenerator(function)) {
2583 MaybeObject* maybe_result = CompileCustomCall( 2250 Handle<Code> code = CompileCustomCall(object, holder,
2584 object, holder, NULL, function, name); 2251 Handle<JSGlobalPropertyCell>::null(),
2585 Object* result; 2252 function, name);
2586 if (!maybe_result->ToObject(&result)) return maybe_result; 2253 // A null handle means bail out to the regular compiler code below.
2587 // Undefined means bail out to regular compiler. 2254 if (!code.is_null()) return code;
2588 if (!result->IsUndefined()) return result;
2589 } 2255 }
2590 2256
2591 Label miss; 2257 Label miss;
2592 2258
2593 GenerateNameCheck(Handle<String>(name), &miss); 2259 GenerateNameCheck(name, &miss);
2594 2260
2595 // Get the receiver from the stack. 2261 // Get the receiver from the stack.
2596 const int argc = arguments().immediate(); 2262 const int argc = arguments().immediate();
2597 __ lw(a1, MemOperand(sp, argc * kPointerSize)); 2263 __ lw(a1, MemOperand(sp, argc * kPointerSize));
2598 2264
2599 // Check that the receiver isn't a smi. 2265 // Check that the receiver isn't a smi.
2600 if (check != NUMBER_CHECK) { 2266 if (check != NUMBER_CHECK) {
2601 __ And(t1, a1, Operand(kSmiTagMask)); 2267 __ And(t1, a1, Operand(kSmiTagMask));
2602 __ Branch(&miss, eq, t1, Operand(zero_reg)); 2268 __ Branch(&miss, eq, t1, Operand(zero_reg));
2603 } 2269 }
2604 2270
2605 // Make sure that it's okay not to patch the on stack receiver 2271 // Make sure that it's okay not to patch the on stack receiver
2606 // unless we're doing a receiver map check. 2272 // unless we're doing a receiver map check.
2607 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); 2273 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK);
2608
2609 SharedFunctionInfo* function_info = function->shared();
2610 switch (check) { 2274 switch (check) {
2611 case RECEIVER_MAP_CHECK: 2275 case RECEIVER_MAP_CHECK:
2612 __ IncrementCounter(masm()->isolate()->counters()->call_const(), 2276 __ IncrementCounter(masm()->isolate()->counters()->call_const(),
2613 1, a0, a3); 2277 1, a0, a3);
2614 2278
2615 // Check that the maps haven't changed. 2279 // Check that the maps haven't changed.
2616 CheckPrototypes(JSObject::cast(object), a1, holder, a0, a3, t0, name, 2280 CheckPrototypes(Handle<JSObject>::cast(object), a1, holder, a0, a3, t0,
2617 &miss); 2281 name, &miss);
2618 2282
2619 // Patch the receiver on the stack with the global proxy if 2283 // Patch the receiver on the stack with the global proxy if
2620 // necessary. 2284 // necessary.
2621 if (object->IsGlobalObject()) { 2285 if (object->IsGlobalObject()) {
2622 __ lw(a3, FieldMemOperand(a1, GlobalObject::kGlobalReceiverOffset)); 2286 __ lw(a3, FieldMemOperand(a1, GlobalObject::kGlobalReceiverOffset));
2623 __ sw(a3, MemOperand(sp, argc * kPointerSize)); 2287 __ sw(a3, MemOperand(sp, argc * kPointerSize));
2624 } 2288 }
2625 break; 2289 break;
2626 2290
2627 case STRING_CHECK: 2291 case STRING_CHECK:
2628 if (!function->IsBuiltin() && !function_info->strict_mode()) { 2292 if (function->IsBuiltin() || function->shared()->strict_mode()) {
2629 // Calling non-strict non-builtins with a value as the receiver
2630 // requires boxing.
2631 __ jmp(&miss);
2632 } else {
2633 // Check that the object is a two-byte string or a symbol. 2293 // Check that the object is a two-byte string or a symbol.
2634 __ GetObjectType(a1, a3, a3); 2294 __ GetObjectType(a1, a3, a3);
2635 __ Branch(&miss, Ugreater_equal, a3, Operand(FIRST_NONSTRING_TYPE)); 2295 __ Branch(&miss, Ugreater_equal, a3, Operand(FIRST_NONSTRING_TYPE));
2636 // Check that the maps starting from the prototype haven't changed. 2296 // Check that the maps starting from the prototype haven't changed.
2637 GenerateDirectLoadGlobalFunctionPrototype( 2297 GenerateDirectLoadGlobalFunctionPrototype(
2638 masm(), Context::STRING_FUNCTION_INDEX, a0, &miss); 2298 masm(), Context::STRING_FUNCTION_INDEX, a0, &miss);
2639 CheckPrototypes(JSObject::cast(object->GetPrototype()), a0, holder, a3, 2299 CheckPrototypes(
2640 a1, t0, name, &miss); 2300 Handle<JSObject>(JSObject::cast(object->GetPrototype())),
2301 a0, holder, a3, a1, t0, name, &miss);
2302 } else {
2303 // Calling non-strict non-builtins with a value as the receiver
2304 // requires boxing.
2305 __ jmp(&miss);
2641 } 2306 }
2642 break; 2307 break;
2643 2308
2644 case NUMBER_CHECK: { 2309 case NUMBER_CHECK:
2645 if (!function->IsBuiltin() && !function_info->strict_mode()) { 2310 if (function->IsBuiltin() || function->shared()->strict_mode()) {
2646 // Calling non-strict non-builtins with a value as the receiver
2647 // requires boxing.
2648 __ jmp(&miss);
2649 } else {
2650 Label fast; 2311 Label fast;
2651 // Check that the object is a smi or a heap number. 2312 // Check that the object is a smi or a heap number.
2652 __ And(t1, a1, Operand(kSmiTagMask)); 2313 __ And(t1, a1, Operand(kSmiTagMask));
2653 __ Branch(&fast, eq, t1, Operand(zero_reg)); 2314 __ Branch(&fast, eq, t1, Operand(zero_reg));
2654 __ GetObjectType(a1, a0, a0); 2315 __ GetObjectType(a1, a0, a0);
2655 __ Branch(&miss, ne, a0, Operand(HEAP_NUMBER_TYPE)); 2316 __ Branch(&miss, ne, a0, Operand(HEAP_NUMBER_TYPE));
2656 __ bind(&fast); 2317 __ bind(&fast);
2657 // Check that the maps starting from the prototype haven't changed. 2318 // Check that the maps starting from the prototype haven't changed.
2658 GenerateDirectLoadGlobalFunctionPrototype( 2319 GenerateDirectLoadGlobalFunctionPrototype(
2659 masm(), Context::NUMBER_FUNCTION_INDEX, a0, &miss); 2320 masm(), Context::NUMBER_FUNCTION_INDEX, a0, &miss);
2660 CheckPrototypes(JSObject::cast(object->GetPrototype()), a0, holder, a3, 2321 CheckPrototypes(
2661 a1, t0, name, &miss); 2322 Handle<JSObject>(JSObject::cast(object->GetPrototype())),
2662 } 2323 a0, holder, a3, a1, t0, name, &miss);
2663 break; 2324 } else {
2664 }
2665
2666 case BOOLEAN_CHECK: {
2667 if (!function->IsBuiltin() && !function_info->strict_mode()) {
2668 // Calling non-strict non-builtins with a value as the receiver 2325 // Calling non-strict non-builtins with a value as the receiver
2669 // requires boxing. 2326 // requires boxing.
2670 __ jmp(&miss); 2327 __ jmp(&miss);
2671 } else { 2328 }
2329 break;
2330
2331 case BOOLEAN_CHECK:
2332 if (function->IsBuiltin() || function->shared()->strict_mode()) {
2672 Label fast; 2333 Label fast;
2673 // Check that the object is a boolean. 2334 // Check that the object is a boolean.
2674 __ LoadRoot(t0, Heap::kTrueValueRootIndex); 2335 __ LoadRoot(t0, Heap::kTrueValueRootIndex);
2675 __ Branch(&fast, eq, a1, Operand(t0)); 2336 __ Branch(&fast, eq, a1, Operand(t0));
2676 __ LoadRoot(t0, Heap::kFalseValueRootIndex); 2337 __ LoadRoot(t0, Heap::kFalseValueRootIndex);
2677 __ Branch(&miss, ne, a1, Operand(t0)); 2338 __ Branch(&miss, ne, a1, Operand(t0));
2678 __ bind(&fast); 2339 __ bind(&fast);
2679 // Check that the maps starting from the prototype haven't changed. 2340 // Check that the maps starting from the prototype haven't changed.
2680 GenerateDirectLoadGlobalFunctionPrototype( 2341 GenerateDirectLoadGlobalFunctionPrototype(
2681 masm(), Context::BOOLEAN_FUNCTION_INDEX, a0, &miss); 2342 masm(), Context::BOOLEAN_FUNCTION_INDEX, a0, &miss);
2682 CheckPrototypes(JSObject::cast(object->GetPrototype()), a0, holder, a3, 2343 CheckPrototypes(
2683 a1, t0, name, &miss); 2344 Handle<JSObject>(JSObject::cast(object->GetPrototype())),
2345 a0, holder, a3, a1, t0, name, &miss);
2346 } else {
2347 // Calling non-strict non-builtins with a value as the receiver
2348 // requires boxing.
2349 __ jmp(&miss);
2684 } 2350 }
2685 break; 2351 break;
2686 } 2352 }
2687 2353
2688 default:
2689 UNREACHABLE();
2690 }
2691
2692 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) 2354 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
2693 ? CALL_AS_FUNCTION 2355 ? CALL_AS_FUNCTION
2694 : CALL_AS_METHOD; 2356 : CALL_AS_METHOD;
2695 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, call_kind); 2357 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, call_kind);
2696 2358
2697 // Handle call cache miss. 2359 // Handle call cache miss.
2698 __ bind(&miss); 2360 __ bind(&miss);
2699 2361
2700 MaybeObject* maybe_result = TryGenerateMissBranch(); 2362 GenerateMissBranch();
2701 if (maybe_result->IsFailure()) return maybe_result;
2702 2363
2703 // Return the generated code. 2364 // Return the generated code.
2704 return TryGetCode(function); 2365 return GetCode(function);
2705 } 2366 }
2706 2367
2707 2368
2708 MaybeObject* CallStubCompiler::CompileCallInterceptor(JSObject* object, 2369 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object,
2709 JSObject* holder, 2370 Handle<JSObject> holder,
2710 String* name) { 2371 Handle<String> name) {
2711 // ----------- S t a t e ------------- 2372 // ----------- S t a t e -------------
2712 // -- a2 : name 2373 // -- a2 : name
2713 // -- ra : return address 2374 // -- ra : return address
2714 // ----------------------------------- 2375 // -----------------------------------
2715 2376
2716 Label miss; 2377 Label miss;
2717 2378
2718 GenerateNameCheck(Handle<String>(name), &miss); 2379 GenerateNameCheck(name, &miss);
2719 2380
2720 // Get the number of arguments. 2381 // Get the number of arguments.
2721 const int argc = arguments().immediate(); 2382 const int argc = arguments().immediate();
2722
2723 LookupResult lookup(isolate()); 2383 LookupResult lookup(isolate());
2724 LookupPostInterceptor(holder, name, &lookup); 2384 LookupPostInterceptor(holder, name, &lookup);
2725 2385
2726 // Get the receiver from the stack. 2386 // Get the receiver from the stack.
2727 __ lw(a1, MemOperand(sp, argc * kPointerSize)); 2387 __ lw(a1, MemOperand(sp, argc * kPointerSize));
2728 2388
2729 CallInterceptorCompiler compiler(this, arguments(), a2, extra_state_); 2389 CallInterceptorCompiler compiler(this, arguments(), a2, extra_state_);
2730 MaybeObject* result = compiler.Compile(masm(), 2390 compiler.Compile(masm(), object, holder, name, &lookup, a1, a3, t0, a0,
2731 object, 2391 &miss);
2732 holder,
2733 name,
2734 &lookup,
2735 a1,
2736 a3,
2737 t0,
2738 a0,
2739 &miss);
2740 if (result->IsFailure()) {
2741 return result;
2742 }
2743 2392
2744 // Move returned value, the function to call, to a1. 2393 // Move returned value, the function to call, to a1.
2745 __ mov(a1, v0); 2394 __ mov(a1, v0);
2746 // Restore receiver. 2395 // Restore receiver.
2747 __ lw(a0, MemOperand(sp, argc * kPointerSize)); 2396 __ lw(a0, MemOperand(sp, argc * kPointerSize));
2748 2397
2749 GenerateCallFunction(masm(), Handle<Object>(object), arguments(), &miss, 2398 GenerateCallFunction(masm(), object, arguments(), &miss, extra_state_);
2750 extra_state_);
2751 2399
2752 // Handle call cache miss. 2400 // Handle call cache miss.
2753 __ bind(&miss); 2401 __ bind(&miss);
2754 MaybeObject* maybe_result = TryGenerateMissBranch(); 2402 GenerateMissBranch();
2755 if (maybe_result->IsFailure()) return maybe_result;
2756 2403
2757 // Return the generated code. 2404 // Return the generated code.
2758 return TryGetCode(INTERCEPTOR, name); 2405 return GetCode(INTERCEPTOR, name);
2759 } 2406 }
2760 2407
2761 2408
2762 MaybeObject* CallStubCompiler::CompileCallGlobal(JSObject* object, 2409 Handle<Code> CallStubCompiler::CompileCallGlobal(
2763 GlobalObject* holder, 2410 Handle<JSObject> object,
2764 JSGlobalPropertyCell* cell, 2411 Handle<GlobalObject> holder,
2765 JSFunction* function, 2412 Handle<JSGlobalPropertyCell> cell,
2766 String* name) { 2413 Handle<JSFunction> function,
2414 Handle<String> name) {
2767 // ----------- S t a t e ------------- 2415 // ----------- S t a t e -------------
2768 // -- a2 : name 2416 // -- a2 : name
2769 // -- ra : return address 2417 // -- ra : return address
2770 // ----------------------------------- 2418 // -----------------------------------
2771 2419
2772 if (HasCustomCallGenerator(function)) { 2420 if (HasCustomCallGenerator(function)) {
2773 MaybeObject* maybe_result = CompileCustomCall( 2421 Handle<Code> code = CompileCustomCall(object, holder, cell, function, name);
2774 object, holder, cell, function, name); 2422 // A null handle means bail out to the regular compiler code below.
2775 Object* result; 2423 if (!code.is_null()) return code;
2776 if (!maybe_result->ToObject(&result)) return maybe_result;
2777 // Undefined means bail out to regular compiler.
2778 if (!result->IsUndefined()) return result;
2779 } 2424 }
2780 2425
2781 Label miss; 2426 Label miss;
2782 2427 GenerateNameCheck(name, &miss);
2783 GenerateNameCheck(Handle<String>(name), &miss);
2784 2428
2785 // Get the number of arguments. 2429 // Get the number of arguments.
2786 const int argc = arguments().immediate(); 2430 const int argc = arguments().immediate();
2787
2788 GenerateGlobalReceiverCheck(object, holder, name, &miss); 2431 GenerateGlobalReceiverCheck(object, holder, name, &miss);
2789 GenerateLoadFunctionFromCell(cell, function, &miss); 2432 GenerateLoadFunctionFromCell(cell, function, &miss);
2790 2433
2791 // Patch the receiver on the stack with the global proxy if 2434 // Patch the receiver on the stack with the global proxy if
2792 // necessary. 2435 // necessary.
2793 if (object->IsGlobalObject()) { 2436 if (object->IsGlobalObject()) {
2794 __ lw(a3, FieldMemOperand(a0, GlobalObject::kGlobalReceiverOffset)); 2437 __ lw(a3, FieldMemOperand(a0, GlobalObject::kGlobalReceiverOffset));
2795 __ sw(a3, MemOperand(sp, argc * kPointerSize)); 2438 __ sw(a3, MemOperand(sp, argc * kPointerSize));
2796 } 2439 }
2797 2440
2798 // Setup the context (function already in r1). 2441 // Setup the context (function already in r1).
2799 __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); 2442 __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset));
2800 2443
2801 // Jump to the cached code (tail call). 2444 // Jump to the cached code (tail call).
2802 Counters* counters = masm()->isolate()->counters(); 2445 Counters* counters = masm()->isolate()->counters();
2803 __ IncrementCounter(counters->call_global_inline(), 1, a3, t0); 2446 __ IncrementCounter(counters->call_global_inline(), 1, a3, t0);
2804 Handle<Code> code(function->code());
2805 ParameterCount expected(function->shared()->formal_parameter_count()); 2447 ParameterCount expected(function->shared()->formal_parameter_count());
2806 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) 2448 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
2807 ? CALL_AS_FUNCTION 2449 ? CALL_AS_FUNCTION
2808 : CALL_AS_METHOD; 2450 : CALL_AS_METHOD;
2809 // We call indirectly through the code field in the function to 2451 // We call indirectly through the code field in the function to
2810 // allow recompilation to take effect without changing any of the 2452 // allow recompilation to take effect without changing any of the
2811 // call sites. 2453 // call sites.
2812 __ lw(a3, FieldMemOperand(a1, JSFunction::kCodeEntryOffset)); 2454 __ lw(a3, FieldMemOperand(a1, JSFunction::kCodeEntryOffset));
2813 __ InvokeCode(a3, expected, arguments(), JUMP_FUNCTION, 2455 __ InvokeCode(a3, expected, arguments(), JUMP_FUNCTION,
2814 NullCallWrapper(), call_kind); 2456 NullCallWrapper(), call_kind);
2815 2457
2816 // Handle call cache miss. 2458 // Handle call cache miss.
2817 __ bind(&miss); 2459 __ bind(&miss);
2818 __ IncrementCounter(counters->call_global_inline_miss(), 1, a1, a3); 2460 __ IncrementCounter(counters->call_global_inline_miss(), 1, a1, a3);
2819 MaybeObject* maybe_result = TryGenerateMissBranch(); 2461 GenerateMissBranch();
2820 if (maybe_result->IsFailure()) return maybe_result;
2821 2462
2822 // Return the generated code. 2463 // Return the generated code.
2823 return TryGetCode(NORMAL, name); 2464 return GetCode(NORMAL, name);
2824 } 2465 }
2825 2466
2826 2467
2827 Handle<Code> StoreStubCompiler::CompileStoreField(Handle<JSObject> object, 2468 Handle<Code> StoreStubCompiler::CompileStoreField(Handle<JSObject> object,
2828 int index, 2469 int index,
2829 Handle<Map> transition, 2470 Handle<Map> transition,
2830 Handle<String> name) { 2471 Handle<String> name) {
2831 // ----------- S t a t e ------------- 2472 // ----------- S t a t e -------------
2832 // -- a0 : value 2473 // -- a0 : value
2833 // -- a1 : receiver 2474 // -- a1 : receiver
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after
3046 2687
3047 GenerateLoadField(object, holder, v0, a3, a1, t0, index, name, &miss); 2688 GenerateLoadField(object, holder, v0, a3, a1, t0, index, name, &miss);
3048 __ bind(&miss); 2689 __ bind(&miss);
3049 GenerateLoadMiss(masm(), Code::LOAD_IC); 2690 GenerateLoadMiss(masm(), Code::LOAD_IC);
3050 2691
3051 // Return the generated code. 2692 // Return the generated code.
3052 return GetCode(FIELD, name); 2693 return GetCode(FIELD, name);
3053 } 2694 }
3054 2695
3055 2696
3056 MaybeObject* LoadStubCompiler::CompileLoadCallback(String* name, 2697 Handle<Code> LoadStubCompiler::CompileLoadCallback(
3057 JSObject* object, 2698 Handle<String> name,
3058 JSObject* holder, 2699 Handle<JSObject> object,
3059 AccessorInfo* callback) { 2700 Handle<JSObject> holder,
2701 Handle<AccessorInfo> callback) {
3060 // ----------- S t a t e ------------- 2702 // ----------- S t a t e -------------
3061 // -- a0 : receiver 2703 // -- a0 : receiver
3062 // -- a2 : name 2704 // -- a2 : name
3063 // -- ra : return address 2705 // -- ra : return address
3064 // ----------------------------------- 2706 // -----------------------------------
3065 Label miss; 2707 Label miss;
3066 2708 GenerateLoadCallback(object, holder, a0, a2, a3, a1, t0, callback, name,
3067 MaybeObject* result = GenerateLoadCallback(object, holder, a0, a2, a3, a1, t0, 2709 &miss);
3068 callback, name, &miss);
3069 if (result->IsFailure()) {
3070 miss.Unuse();
3071 return result;
3072 }
3073
3074 __ bind(&miss); 2710 __ bind(&miss);
3075 GenerateLoadMiss(masm(), Code::LOAD_IC); 2711 GenerateLoadMiss(masm(), Code::LOAD_IC);
3076 2712
3077 // Return the generated code. 2713 // Return the generated code.
3078 return TryGetCode(CALLBACKS, name); 2714 return GetCode(CALLBACKS, name);
3079 } 2715 }
3080 2716
3081 2717
3082 Handle<Code> LoadStubCompiler::CompileLoadConstant(Handle<JSObject> object, 2718 Handle<Code> LoadStubCompiler::CompileLoadConstant(Handle<JSObject> object,
3083 Handle<JSObject> holder, 2719 Handle<JSObject> holder,
3084 Handle<Object> value, 2720 Handle<Object> value,
3085 Handle<String> name) { 2721 Handle<String> name) {
3086 // ----------- S t a t e ------------- 2722 // ----------- S t a t e -------------
3087 // -- a0 : receiver 2723 // -- a0 : receiver
3088 // -- a2 : name 2724 // -- a2 : name
3089 // -- ra : return address 2725 // -- ra : return address
3090 // ----------------------------------- 2726 // -----------------------------------
3091 Label miss; 2727 Label miss;
3092 2728
3093 GenerateLoadConstant(object, holder, a0, a3, a1, t0, value, name, &miss); 2729 GenerateLoadConstant(object, holder, a0, a3, a1, t0, value, name, &miss);
3094 __ bind(&miss); 2730 __ bind(&miss);
3095 GenerateLoadMiss(masm(), Code::LOAD_IC); 2731 GenerateLoadMiss(masm(), Code::LOAD_IC);
3096 2732
3097 // Return the generated code. 2733 // Return the generated code.
3098 return GetCode(CONSTANT_FUNCTION, name); 2734 return GetCode(CONSTANT_FUNCTION, name);
3099 } 2735 }
3100 2736
3101 2737
3102 MaybeObject* LoadStubCompiler::CompileLoadInterceptor(JSObject* object, 2738 Handle<Code> LoadStubCompiler::CompileLoadInterceptor(Handle<JSObject> object,
3103 JSObject* holder, 2739 Handle<JSObject> holder,
3104 String* name) { 2740 Handle<String> name) {
3105 // ----------- S t a t e ------------- 2741 // ----------- S t a t e -------------
3106 // -- a0 : receiver 2742 // -- a0 : receiver
3107 // -- a2 : name 2743 // -- a2 : name
3108 // -- ra : return address 2744 // -- ra : return address
3109 // -- [sp] : receiver 2745 // -- [sp] : receiver
3110 // ----------------------------------- 2746 // -----------------------------------
3111 Label miss; 2747 Label miss;
3112 2748
3113 LookupResult lookup(isolate()); 2749 LookupResult lookup(isolate());
3114 LookupPostInterceptor(holder, name, &lookup); 2750 LookupPostInterceptor(holder, name, &lookup);
3115 GenerateLoadInterceptor(object, 2751 GenerateLoadInterceptor(object, holder, &lookup, a0, a2, a3, a1, t0, name,
3116 holder,
3117 &lookup,
3118 a0,
3119 a2,
3120 a3,
3121 a1,
3122 t0,
3123 name,
3124 &miss); 2752 &miss);
3125 __ bind(&miss); 2753 __ bind(&miss);
3126 GenerateLoadMiss(masm(), Code::LOAD_IC); 2754 GenerateLoadMiss(masm(), Code::LOAD_IC);
3127 2755
3128 // Return the generated code. 2756 // Return the generated code.
3129 return TryGetCode(INTERCEPTOR, name); 2757 return GetCode(INTERCEPTOR, name);
3130 } 2758 }
3131 2759
3132 2760
3133 Handle<Code> LoadStubCompiler::CompileLoadGlobal( 2761 Handle<Code> LoadStubCompiler::CompileLoadGlobal(
3134 Handle<JSObject> object, 2762 Handle<JSObject> object,
3135 Handle<GlobalObject> holder, 2763 Handle<GlobalObject> holder,
3136 Handle<JSGlobalPropertyCell> cell, 2764 Handle<JSGlobalPropertyCell> cell,
3137 Handle<String> name, 2765 Handle<String> name,
3138 bool is_dont_delete) { 2766 bool is_dont_delete) {
3139 // ----------- S t a t e ------------- 2767 // ----------- S t a t e -------------
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
3193 __ Branch(&miss, ne, a0, Operand(name)); 2821 __ Branch(&miss, ne, a0, Operand(name));
3194 2822
3195 GenerateLoadField(receiver, holder, a1, a2, a3, t0, index, name, &miss); 2823 GenerateLoadField(receiver, holder, a1, a2, a3, t0, index, name, &miss);
3196 __ bind(&miss); 2824 __ bind(&miss);
3197 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 2825 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
3198 2826
3199 return GetCode(FIELD, name); 2827 return GetCode(FIELD, name);
3200 } 2828 }
3201 2829
3202 2830
3203 MaybeObject* KeyedLoadStubCompiler::CompileLoadCallback( 2831 Handle<Code> KeyedLoadStubCompiler::CompileLoadCallback(
3204 String* name, 2832 Handle<String> name,
3205 JSObject* receiver, 2833 Handle<JSObject> receiver,
3206 JSObject* holder, 2834 Handle<JSObject> holder,
3207 AccessorInfo* callback) { 2835 Handle<AccessorInfo> callback) {
3208 // ----------- S t a t e ------------- 2836 // ----------- S t a t e -------------
3209 // -- ra : return address 2837 // -- ra : return address
3210 // -- a0 : key 2838 // -- a0 : key
3211 // -- a1 : receiver 2839 // -- a1 : receiver
3212 // ----------------------------------- 2840 // -----------------------------------
3213 Label miss; 2841 Label miss;
3214 2842
3215 // Check the key is the cached one. 2843 // Check the key is the cached one.
3216 __ Branch(&miss, ne, a0, Operand(Handle<String>(name))); 2844 __ Branch(&miss, ne, a0, Operand(name));
3217 2845
3218 MaybeObject* result = GenerateLoadCallback(receiver, holder, a1, a0, a2, a3, 2846 GenerateLoadCallback(receiver, holder, a1, a0, a2, a3, t0, callback, name,
3219 t0, callback, name, &miss); 2847 &miss);
3220 if (result->IsFailure()) {
3221 miss.Unuse();
3222 return result;
3223 }
3224
3225 __ bind(&miss); 2848 __ bind(&miss);
3226 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 2849 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
3227 2850
3228 return TryGetCode(CALLBACKS, name); 2851 return GetCode(CALLBACKS, name);
3229 } 2852 }
3230 2853
3231 2854
3232 Handle<Code> KeyedLoadStubCompiler::CompileLoadConstant( 2855 Handle<Code> KeyedLoadStubCompiler::CompileLoadConstant(
3233 Handle<String> name, 2856 Handle<String> name,
3234 Handle<JSObject> receiver, 2857 Handle<JSObject> receiver,
3235 Handle<JSObject> holder, 2858 Handle<JSObject> holder,
3236 Handle<Object> value) { 2859 Handle<Object> value) {
3237 // ----------- S t a t e ------------- 2860 // ----------- S t a t e -------------
3238 // -- ra : return address 2861 // -- ra : return address
3239 // -- a0 : key 2862 // -- a0 : key
3240 // -- a1 : receiver 2863 // -- a1 : receiver
3241 // ----------------------------------- 2864 // -----------------------------------
3242 Label miss; 2865 Label miss;
3243 2866
3244 // Check the key is the cached one. 2867 // Check the key is the cached one.
3245 __ Branch(&miss, ne, a0, Operand(name)); 2868 __ Branch(&miss, ne, a0, Operand(name));
3246 2869
3247 GenerateLoadConstant(receiver, holder, a1, a2, a3, t0, value, name, &miss); 2870 GenerateLoadConstant(receiver, holder, a1, a2, a3, t0, value, name, &miss);
3248 __ bind(&miss); 2871 __ bind(&miss);
3249 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 2872 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
3250 2873
3251 // Return the generated code. 2874 // Return the generated code.
3252 return GetCode(CONSTANT_FUNCTION, name); 2875 return GetCode(CONSTANT_FUNCTION, name);
3253 } 2876 }
3254 2877
3255 2878
3256 MaybeObject* KeyedLoadStubCompiler::CompileLoadInterceptor(JSObject* receiver, 2879 Handle<Code> KeyedLoadStubCompiler::CompileLoadInterceptor(
3257 JSObject* holder, 2880 Handle<JSObject> receiver,
3258 String* name) { 2881 Handle<JSObject> holder,
2882 Handle<String> name) {
3259 // ----------- S t a t e ------------- 2883 // ----------- S t a t e -------------
3260 // -- ra : return address 2884 // -- ra : return address
3261 // -- a0 : key 2885 // -- a0 : key
3262 // -- a1 : receiver 2886 // -- a1 : receiver
3263 // ----------------------------------- 2887 // -----------------------------------
3264 Label miss; 2888 Label miss;
3265 2889
3266 // Check the key is the cached one. 2890 // Check the key is the cached one.
3267 __ Branch(&miss, ne, a0, Operand(Handle<String>(name))); 2891 __ Branch(&miss, ne, a0, Operand(name));
3268 2892
3269 LookupResult lookup(isolate()); 2893 LookupResult lookup(isolate());
3270 LookupPostInterceptor(holder, name, &lookup); 2894 LookupPostInterceptor(holder, name, &lookup);
3271 GenerateLoadInterceptor(receiver, 2895 GenerateLoadInterceptor(receiver, holder, &lookup, a1, a0, a2, a3, t0, name,
3272 holder,
3273 &lookup,
3274 a1,
3275 a0,
3276 a2,
3277 a3,
3278 t0,
3279 name,
3280 &miss); 2896 &miss);
3281 __ bind(&miss); 2897 __ bind(&miss);
3282 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 2898 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
3283 2899
3284 return TryGetCode(INTERCEPTOR, name); 2900 return GetCode(INTERCEPTOR, name);
3285 } 2901 }
3286 2902
3287 2903
3288 Handle<Code> KeyedLoadStubCompiler::CompileLoadArrayLength( 2904 Handle<Code> KeyedLoadStubCompiler::CompileLoadArrayLength(
3289 Handle<String> name) { 2905 Handle<String> name) {
3290 // ----------- S t a t e ------------- 2906 // ----------- S t a t e -------------
3291 // -- ra : return address 2907 // -- ra : return address
3292 // -- a0 : key 2908 // -- a0 : key
3293 // -- a1 : receiver 2909 // -- a1 : receiver
3294 // ----------------------------------- 2910 // -----------------------------------
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
3489 3105
3490 __ bind(&miss); 3106 __ bind(&miss);
3491 Handle<Code> miss_ic = isolate()->builtins()->KeyedStoreIC_Miss(); 3107 Handle<Code> miss_ic = isolate()->builtins()->KeyedStoreIC_Miss();
3492 __ Jump(miss_ic, RelocInfo::CODE_TARGET); 3108 __ Jump(miss_ic, RelocInfo::CODE_TARGET);
3493 3109
3494 // Return the generated code. 3110 // Return the generated code.
3495 return GetCode(NORMAL, factory()->empty_string(), MEGAMORPHIC); 3111 return GetCode(NORMAL, factory()->empty_string(), MEGAMORPHIC);
3496 } 3112 }
3497 3113
3498 3114
3499 MaybeObject* ConstructStubCompiler::CompileConstructStub(JSFunction* function) { 3115 Handle<Code> ConstructStubCompiler::CompileConstructStub(
3116 Handle<JSFunction> function) {
3500 // a0 : argc 3117 // a0 : argc
3501 // a1 : constructor 3118 // a1 : constructor
3502 // ra : return address 3119 // ra : return address
3503 // [sp] : last argument 3120 // [sp] : last argument
3504 Label generic_stub_call; 3121 Label generic_stub_call;
3505 3122
3506 // Use t7 for holding undefined which is used in several places below. 3123 // Use t7 for holding undefined which is used in several places below.
3507 __ LoadRoot(t7, Heap::kUndefinedValueRootIndex); 3124 __ LoadRoot(t7, Heap::kUndefinedValueRootIndex);
3508 3125
3509 #ifdef ENABLE_DEBUGGER_SUPPORT 3126 #ifdef ENABLE_DEBUGGER_SUPPORT
(...skipping 24 matching lines...) Expand all
3534 __ Check(ne, "Function constructed by construct stub.", 3151 __ Check(ne, "Function constructed by construct stub.",
3535 a3, Operand(JS_FUNCTION_TYPE)); 3152 a3, Operand(JS_FUNCTION_TYPE));
3536 #endif 3153 #endif
3537 3154
3538 // Now allocate the JSObject in new space. 3155 // Now allocate the JSObject in new space.
3539 // a0: argc 3156 // a0: argc
3540 // a1: constructor function 3157 // a1: constructor function
3541 // a2: initial map 3158 // a2: initial map
3542 // t7: undefined 3159 // t7: undefined
3543 __ lbu(a3, FieldMemOperand(a2, Map::kInstanceSizeOffset)); 3160 __ lbu(a3, FieldMemOperand(a2, Map::kInstanceSizeOffset));
3544 __ AllocateInNewSpace(a3, 3161 __ AllocateInNewSpace(a3, t4, t5, t6, &generic_stub_call, SIZE_IN_WORDS);
3545 t4,
3546 t5,
3547 t6,
3548 &generic_stub_call,
3549 SIZE_IN_WORDS);
3550 3162
3551 // Allocated the JSObject, now initialize the fields. Map is set to initial 3163 // Allocated the JSObject, now initialize the fields. Map is set to initial
3552 // map and properties and elements are set to empty fixed array. 3164 // map and properties and elements are set to empty fixed array.
3553 // a0: argc 3165 // a0: argc
3554 // a1: constructor function 3166 // a1: constructor function
3555 // a2: initial map 3167 // a2: initial map
3556 // a3: object size (in words) 3168 // a3: object size (in words)
3557 // t4: JSObject (not tagged) 3169 // t4: JSObject (not tagged)
3558 // t7: undefined 3170 // t7: undefined
3559 __ LoadRoot(t6, Heap::kEmptyFixedArrayRootIndex); 3171 __ LoadRoot(t6, Heap::kEmptyFixedArrayRootIndex);
(...skipping 14 matching lines...) Expand all
3574 3186
3575 // Fill all the in-object properties with undefined. 3187 // Fill all the in-object properties with undefined.
3576 // a0: argc 3188 // a0: argc
3577 // a1: first argument 3189 // a1: first argument
3578 // a3: object size (in words) 3190 // a3: object size (in words)
3579 // t4: JSObject (not tagged) 3191 // t4: JSObject (not tagged)
3580 // t5: First in-object property of JSObject (not tagged) 3192 // t5: First in-object property of JSObject (not tagged)
3581 // t7: undefined 3193 // t7: undefined
3582 // Fill the initialized properties with a constant value or a passed argument 3194 // Fill the initialized properties with a constant value or a passed argument
3583 // depending on the this.x = ...; assignment in the function. 3195 // depending on the this.x = ...; assignment in the function.
3584 SharedFunctionInfo* shared = function->shared(); 3196 Handle<SharedFunctionInfo> shared(function->shared());
3585 for (int i = 0; i < shared->this_property_assignments_count(); i++) { 3197 for (int i = 0; i < shared->this_property_assignments_count(); i++) {
3586 if (shared->IsThisPropertyAssignmentArgument(i)) { 3198 if (shared->IsThisPropertyAssignmentArgument(i)) {
3587 Label not_passed, next; 3199 Label not_passed, next;
3588 // Check if the argument assigned to the property is actually passed. 3200 // Check if the argument assigned to the property is actually passed.
3589 int arg_number = shared->GetThisPropertyAssignmentArgument(i); 3201 int arg_number = shared->GetThisPropertyAssignmentArgument(i);
3590 __ Branch(&not_passed, less_equal, a0, Operand(arg_number)); 3202 __ Branch(&not_passed, less_equal, a0, Operand(arg_number));
3591 // Argument passed - find it on the stack. 3203 // Argument passed - find it on the stack.
3592 __ lw(a2, MemOperand(a1, (arg_number + 1) * -kPointerSize)); 3204 __ lw(a2, MemOperand(a1, (arg_number + 1) * -kPointerSize));
3593 __ sw(a2, MemOperand(t5)); 3205 __ sw(a2, MemOperand(t5));
3594 __ Addu(t5, t5, kPointerSize); 3206 __ Addu(t5, t5, kPointerSize);
(...skipping 451 matching lines...) Expand 10 before | Expand all | Expand 10 after
4046 // -- ra : return address 3658 // -- ra : return address
4047 // -- a0 : key 3659 // -- a0 : key
4048 // -- a1 : receiver 3660 // -- a1 : receiver
4049 // ----------------------------------- 3661 // -----------------------------------
4050 3662
4051 __ Push(a1, a0); 3663 __ Push(a1, a0);
4052 3664
4053 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1); 3665 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1);
4054 3666
4055 __ bind(&miss_force_generic); 3667 __ bind(&miss_force_generic);
4056 Code* stub = masm->isolate()->builtins()->builtin( 3668 Handle<Code> stub =
4057 Builtins::kKeyedLoadIC_MissForceGeneric); 3669 masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric();
4058 __ Jump(Handle<Code>(stub), RelocInfo::CODE_TARGET); 3670 __ Jump(stub, RelocInfo::CODE_TARGET);
4059 } 3671 }
4060 3672
4061 3673
4062 void KeyedStoreStubCompiler::GenerateStoreExternalArray( 3674 void KeyedStoreStubCompiler::GenerateStoreExternalArray(
4063 MacroAssembler* masm, 3675 MacroAssembler* masm,
4064 ElementsKind elements_kind) { 3676 ElementsKind elements_kind) {
4065 // ---------- S t a t e -------------- 3677 // ---------- S t a t e --------------
4066 // -- a0 : value 3678 // -- a0 : value
4067 // -- a1 : key 3679 // -- a1 : key
4068 // -- a2 : receiver 3680 // -- a2 : receiver
(...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after
4476 STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize < kPointerSizeLog2); 4088 STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize < kPointerSizeLog2);
4477 __ sll(t0, a0, kPointerSizeLog2 - kSmiTagSize); 4089 __ sll(t0, a0, kPointerSizeLog2 - kSmiTagSize);
4478 __ Addu(t0, t0, a3); 4090 __ Addu(t0, t0, a3);
4479 __ lw(t0, MemOperand(t0)); 4091 __ lw(t0, MemOperand(t0));
4480 __ LoadRoot(t1, Heap::kTheHoleValueRootIndex); 4092 __ LoadRoot(t1, Heap::kTheHoleValueRootIndex);
4481 __ Branch(&miss_force_generic, eq, t0, Operand(t1)); 4093 __ Branch(&miss_force_generic, eq, t0, Operand(t1));
4482 __ mov(v0, t0); 4094 __ mov(v0, t0);
4483 __ Ret(); 4095 __ Ret();
4484 4096
4485 __ bind(&miss_force_generic); 4097 __ bind(&miss_force_generic);
4486 Code* stub = masm->isolate()->builtins()->builtin( 4098 Handle<Code> stub =
4487 Builtins::kKeyedLoadIC_MissForceGeneric); 4099 masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric();
4488 __ Jump(Handle<Code>(stub), RelocInfo::CODE_TARGET); 4100 __ Jump(stub, RelocInfo::CODE_TARGET);
4489 } 4101 }
4490 4102
4491 4103
4492 void KeyedLoadStubCompiler::GenerateLoadFastDoubleElement( 4104 void KeyedLoadStubCompiler::GenerateLoadFastDoubleElement(
4493 MacroAssembler* masm) { 4105 MacroAssembler* masm) {
4494 // ----------- S t a t e ------------- 4106 // ----------- S t a t e -------------
4495 // -- ra : return address 4107 // -- ra : return address
4496 // -- a0 : key 4108 // -- a0 : key
4497 // -- a1 : receiver 4109 // -- a1 : receiver
4498 // ----------------------------------- 4110 // -----------------------------------
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after
4711 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss(); 4323 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss();
4712 __ Jump(ic_miss, RelocInfo::CODE_TARGET); 4324 __ Jump(ic_miss, RelocInfo::CODE_TARGET);
4713 } 4325 }
4714 4326
4715 4327
4716 #undef __ 4328 #undef __
4717 4329
4718 } } // namespace v8::internal 4330 } } // namespace v8::internal
4719 4331
4720 #endif // V8_TARGET_ARCH_MIPS 4332 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « src/mips/macro-assembler-mips.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698