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