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

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

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

Powered by Google App Engine
This is Rietveld 408576698