| OLD | NEW | 
|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. | 
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #include "src/v8.h" | 5 #include "src/v8.h" | 
| 6 | 6 | 
| 7 #if V8_TARGET_ARCH_MIPS64 | 7 #if V8_TARGET_ARCH_MIPS64 | 
| 8 | 8 | 
| 9 #include "src/codegen.h" | 9 #include "src/codegen.h" | 
| 10 #include "src/ic-inl.h" | 10 #include "src/ic-inl.h" | 
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 87 | 87 | 
| 88   // Jump to the first instruction in the code stub. | 88   // Jump to the first instruction in the code stub. | 
| 89   __ Daddu(at, code, Operand(Code::kHeaderSize - kHeapObjectTag)); | 89   __ Daddu(at, code, Operand(Code::kHeaderSize - kHeapObjectTag)); | 
| 90   __ Jump(at); | 90   __ Jump(at); | 
| 91 | 91 | 
| 92   // Miss: fall through. | 92   // Miss: fall through. | 
| 93   __ bind(&miss); | 93   __ bind(&miss); | 
| 94 } | 94 } | 
| 95 | 95 | 
| 96 | 96 | 
| 97 void StubCompiler::GenerateDictionaryNegativeLookup(MacroAssembler* masm, | 97 void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup( | 
| 98                                                     Label* miss_label, | 98     MacroAssembler* masm, Label* miss_label, Register receiver, | 
| 99                                                     Register receiver, | 99     Handle<Name> name, Register scratch0, Register scratch1) { | 
| 100                                                     Handle<Name> name, |  | 
| 101                                                     Register scratch0, |  | 
| 102                                                     Register scratch1) { |  | 
| 103   ASSERT(name->IsUniqueName()); | 100   ASSERT(name->IsUniqueName()); | 
| 104   ASSERT(!receiver.is(scratch0)); | 101   ASSERT(!receiver.is(scratch0)); | 
| 105   Counters* counters = masm->isolate()->counters(); | 102   Counters* counters = masm->isolate()->counters(); | 
| 106   __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1); | 103   __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1); | 
| 107   __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); | 104   __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); | 
| 108 | 105 | 
| 109   Label done; | 106   Label done; | 
| 110 | 107 | 
| 111   const int kInterceptorOrAccessCheckNeededMask = | 108   const int kInterceptorOrAccessCheckNeededMask = | 
| 112       (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded); | 109       (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded); | 
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 233              extra3); | 230              extra3); | 
| 234 | 231 | 
| 235   // Cache miss: Fall-through and let caller handle the miss by | 232   // Cache miss: Fall-through and let caller handle the miss by | 
| 236   // entering the runtime system. | 233   // entering the runtime system. | 
| 237   __ bind(&miss); | 234   __ bind(&miss); | 
| 238   __ IncrementCounter(counters->megamorphic_stub_cache_misses(), 1, | 235   __ IncrementCounter(counters->megamorphic_stub_cache_misses(), 1, | 
| 239                       extra2, extra3); | 236                       extra2, extra3); | 
| 240 } | 237 } | 
| 241 | 238 | 
| 242 | 239 | 
| 243 void StubCompiler::GenerateLoadGlobalFunctionPrototype(MacroAssembler* masm, | 240 void NamedLoadHandlerCompiler::GenerateDirectLoadGlobalFunctionPrototype( | 
| 244                                                        int index, | 241     MacroAssembler* masm, int index, Register prototype, Label* miss) { | 
| 245                                                        Register prototype) { |  | 
| 246   // Load the global or builtins object from the current context. |  | 
| 247   __ ld(prototype, |  | 
| 248         MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); |  | 
| 249   // Load the native context from the global or builtins object. |  | 
| 250   __ ld(prototype, |  | 
| 251          FieldMemOperand(prototype, GlobalObject::kNativeContextOffset)); |  | 
| 252   // Load the function from the native context. |  | 
| 253   __ ld(prototype, MemOperand(prototype, Context::SlotOffset(index))); |  | 
| 254   // Load the initial map.  The global functions all have initial maps. |  | 
| 255   __ ld(prototype, |  | 
| 256          FieldMemOperand(prototype, JSFunction::kPrototypeOrInitialMapOffset)); |  | 
| 257   // Load the prototype from the initial map. |  | 
| 258   __ ld(prototype, FieldMemOperand(prototype, Map::kPrototypeOffset)); |  | 
| 259 } |  | 
| 260 |  | 
| 261 |  | 
| 262 void StubCompiler::GenerateDirectLoadGlobalFunctionPrototype( |  | 
| 263     MacroAssembler* masm, |  | 
| 264     int index, |  | 
| 265     Register prototype, |  | 
| 266     Label* miss) { |  | 
| 267   Isolate* isolate = masm->isolate(); | 242   Isolate* isolate = masm->isolate(); | 
| 268   // Get the global function with the given index. | 243   // Get the global function with the given index. | 
| 269   Handle<JSFunction> function( | 244   Handle<JSFunction> function( | 
| 270       JSFunction::cast(isolate->native_context()->get(index))); | 245       JSFunction::cast(isolate->native_context()->get(index))); | 
| 271 | 246 | 
| 272   // Check we're still in the same context. | 247   // Check we're still in the same context. | 
| 273   Register scratch = prototype; | 248   Register scratch = prototype; | 
| 274   const int offset = Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX); | 249   const int offset = Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX); | 
| 275   __ ld(scratch, MemOperand(cp, offset)); | 250   __ ld(scratch, MemOperand(cp, offset)); | 
| 276   __ ld(scratch, FieldMemOperand(scratch, GlobalObject::kNativeContextOffset)); | 251   __ ld(scratch, FieldMemOperand(scratch, GlobalObject::kNativeContextOffset)); | 
| 277   __ ld(scratch, MemOperand(scratch, Context::SlotOffset(index))); | 252   __ ld(scratch, MemOperand(scratch, Context::SlotOffset(index))); | 
| 278   __ li(at, function); | 253   __ li(at, function); | 
| 279   __ Branch(miss, ne, at, Operand(scratch)); | 254   __ Branch(miss, ne, at, Operand(scratch)); | 
| 280 | 255 | 
| 281   // Load its initial map. The global functions all have initial maps. | 256   // Load its initial map. The global functions all have initial maps. | 
| 282   __ li(prototype, Handle<Map>(function->initial_map())); | 257   __ li(prototype, Handle<Map>(function->initial_map())); | 
| 283   // Load the prototype from the initial map. | 258   // Load the prototype from the initial map. | 
| 284   __ ld(prototype, FieldMemOperand(prototype, Map::kPrototypeOffset)); | 259   __ ld(prototype, FieldMemOperand(prototype, Map::kPrototypeOffset)); | 
| 285 } | 260 } | 
| 286 | 261 | 
| 287 | 262 | 
| 288 void StubCompiler::GenerateFastPropertyLoad(MacroAssembler* masm, | 263 void NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype( | 
| 289                                             Register dst, | 264     MacroAssembler* masm, Register receiver, Register scratch1, | 
| 290                                             Register src, | 265     Register scratch2, Label* miss_label) { | 
| 291                                             bool inobject, |  | 
| 292                                             int index, |  | 
| 293                                             Representation representation) { |  | 
| 294   ASSERT(!representation.IsDouble()); |  | 
| 295   int offset = index * kPointerSize; |  | 
| 296   if (!inobject) { |  | 
| 297     // Calculate the offset into the properties array. |  | 
| 298     offset = offset + FixedArray::kHeaderSize; |  | 
| 299     __ ld(dst, FieldMemOperand(src, JSObject::kPropertiesOffset)); |  | 
| 300     src = dst; |  | 
| 301   } |  | 
| 302   __ ld(dst, FieldMemOperand(src, offset)); |  | 
| 303 } |  | 
| 304 |  | 
| 305 |  | 
| 306 void StubCompiler::GenerateLoadArrayLength(MacroAssembler* masm, |  | 
| 307                                            Register receiver, |  | 
| 308                                            Register scratch, |  | 
| 309                                            Label* miss_label) { |  | 
| 310   // Check that the receiver isn't a smi. |  | 
| 311   __ JumpIfSmi(receiver, miss_label); |  | 
| 312 |  | 
| 313   // Check that the object is a JS array. |  | 
| 314   __ GetObjectType(receiver, scratch, scratch); |  | 
| 315   __ Branch(miss_label, ne, scratch, Operand(JS_ARRAY_TYPE)); |  | 
| 316 |  | 
| 317   // Load length directly from the JS array. |  | 
| 318   __ Ret(USE_DELAY_SLOT); |  | 
| 319   __ ld(v0, FieldMemOperand(receiver, JSArray::kLengthOffset)); |  | 
| 320 } |  | 
| 321 |  | 
| 322 |  | 
| 323 void StubCompiler::GenerateLoadFunctionPrototype(MacroAssembler* masm, |  | 
| 324                                                  Register receiver, |  | 
| 325                                                  Register scratch1, |  | 
| 326                                                  Register scratch2, |  | 
| 327                                                  Label* miss_label) { |  | 
| 328   __ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label); | 266   __ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label); | 
| 329   __ Ret(USE_DELAY_SLOT); | 267   __ Ret(USE_DELAY_SLOT); | 
| 330   __ mov(v0, scratch1); | 268   __ mov(v0, scratch1); | 
| 331 } | 269 } | 
| 332 | 270 | 
| 333 | 271 | 
| 334 void StubCompiler::GenerateCheckPropertyCell(MacroAssembler* masm, | 272 void PropertyHandlerCompiler::GenerateCheckPropertyCell( | 
| 335                                              Handle<JSGlobalObject> global, | 273     MacroAssembler* masm, Handle<JSGlobalObject> global, Handle<Name> name, | 
| 336                                              Handle<Name> name, | 274     Register scratch, Label* miss) { | 
| 337                                              Register scratch, |  | 
| 338                                              Label* miss) { |  | 
| 339   Handle<Cell> cell = JSGlobalObject::EnsurePropertyCell(global, name); | 275   Handle<Cell> cell = JSGlobalObject::EnsurePropertyCell(global, name); | 
| 340   ASSERT(cell->value()->IsTheHole()); | 276   ASSERT(cell->value()->IsTheHole()); | 
| 341   __ li(scratch, Operand(cell)); | 277   __ li(scratch, Operand(cell)); | 
| 342   __ ld(scratch, FieldMemOperand(scratch, Cell::kValueOffset)); | 278   __ ld(scratch, FieldMemOperand(scratch, Cell::kValueOffset)); | 
| 343   __ LoadRoot(at, Heap::kTheHoleValueRootIndex); | 279   __ LoadRoot(at, Heap::kTheHoleValueRootIndex); | 
| 344   __ Branch(miss, ne, scratch, Operand(at)); | 280   __ Branch(miss, ne, scratch, Operand(at)); | 
| 345 } | 281 } | 
| 346 | 282 | 
| 347 | 283 | 
| 348 void StoreStubCompiler::GenerateNegativeHolderLookup( | 284 void NamedStoreHandlerCompiler::GenerateNegativeHolderLookup( | 
| 349     MacroAssembler* masm, | 285     MacroAssembler* masm, Handle<JSObject> holder, Register holder_reg, | 
| 350     Handle<JSObject> holder, | 286     Handle<Name> name, Label* miss) { | 
| 351     Register holder_reg, |  | 
| 352     Handle<Name> name, |  | 
| 353     Label* miss) { |  | 
| 354   if (holder->IsJSGlobalObject()) { | 287   if (holder->IsJSGlobalObject()) { | 
| 355     GenerateCheckPropertyCell( | 288     GenerateCheckPropertyCell( | 
| 356         masm, Handle<JSGlobalObject>::cast(holder), name, scratch1(), miss); | 289         masm, Handle<JSGlobalObject>::cast(holder), name, scratch1(), miss); | 
| 357   } else if (!holder->HasFastProperties() && !holder->IsJSGlobalProxy()) { | 290   } else if (!holder->HasFastProperties() && !holder->IsJSGlobalProxy()) { | 
| 358     GenerateDictionaryNegativeLookup( | 291     GenerateDictionaryNegativeLookup( | 
| 359         masm, miss, holder_reg, name, scratch1(), scratch2()); | 292         masm, miss, holder_reg, name, scratch1(), scratch2()); | 
| 360   } | 293   } | 
| 361 } | 294 } | 
| 362 | 295 | 
| 363 | 296 | 
| 364 // Generate StoreTransition code, value is passed in a0 register. | 297 // Generate StoreTransition code, value is passed in a0 register. | 
| 365 // After executing generated code, the receiver_reg and name_reg | 298 // After executing generated code, the receiver_reg and name_reg | 
| 366 // may be clobbered. | 299 // may be clobbered. | 
| 367 void StoreStubCompiler::GenerateStoreTransition(MacroAssembler* masm, | 300 void NamedStoreHandlerCompiler::GenerateStoreTransition( | 
| 368                                                 Handle<JSObject> object, | 301     MacroAssembler* masm, Handle<JSObject> object, LookupResult* lookup, | 
| 369                                                 LookupResult* lookup, | 302     Handle<Map> transition, Handle<Name> name, Register receiver_reg, | 
| 370                                                 Handle<Map> transition, | 303     Register storage_reg, Register value_reg, Register scratch1, | 
| 371                                                 Handle<Name> name, | 304     Register scratch2, Register scratch3, Label* miss_label, Label* slow) { | 
| 372                                                 Register receiver_reg, |  | 
| 373                                                 Register storage_reg, |  | 
| 374                                                 Register value_reg, |  | 
| 375                                                 Register scratch1, |  | 
| 376                                                 Register scratch2, |  | 
| 377                                                 Register scratch3, |  | 
| 378                                                 Label* miss_label, |  | 
| 379                                                 Label* slow) { |  | 
| 380   // a0 : value. | 305   // a0 : value. | 
| 381   Label exit; | 306   Label exit; | 
| 382 | 307 | 
| 383   int descriptor = transition->LastAdded(); | 308   int descriptor = transition->LastAdded(); | 
| 384   DescriptorArray* descriptors = transition->instance_descriptors(); | 309   DescriptorArray* descriptors = transition->instance_descriptors(); | 
| 385   PropertyDetails details = descriptors->GetDetails(descriptor); | 310   PropertyDetails details = descriptors->GetDetails(descriptor); | 
| 386   Representation representation = details.representation(); | 311   Representation representation = details.representation(); | 
| 387   ASSERT(!representation.IsNone()); | 312   ASSERT(!representation.IsNone()); | 
| 388 | 313 | 
| 389   if (details.type() == CONSTANT) { | 314   if (details.type() == CONSTANT) { | 
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 540   __ bind(&exit); | 465   __ bind(&exit); | 
| 541   __ Ret(USE_DELAY_SLOT); | 466   __ Ret(USE_DELAY_SLOT); | 
| 542   __ mov(v0, a0); | 467   __ mov(v0, a0); | 
| 543 } | 468 } | 
| 544 | 469 | 
| 545 | 470 | 
| 546 // Generate StoreField code, value is passed in a0 register. | 471 // Generate StoreField code, value is passed in a0 register. | 
| 547 // When leaving generated code after success, the receiver_reg and name_reg | 472 // When leaving generated code after success, the receiver_reg and name_reg | 
| 548 // may be clobbered.  Upon branch to miss_label, the receiver and name | 473 // may be clobbered.  Upon branch to miss_label, the receiver and name | 
| 549 // registers have their original values. | 474 // registers have their original values. | 
| 550 void StoreStubCompiler::GenerateStoreField(MacroAssembler* masm, | 475 void NamedStoreHandlerCompiler::GenerateStoreField( | 
| 551                                            Handle<JSObject> object, | 476     MacroAssembler* masm, Handle<JSObject> object, LookupResult* lookup, | 
| 552                                            LookupResult* lookup, | 477     Register receiver_reg, Register name_reg, Register value_reg, | 
| 553                                            Register receiver_reg, | 478     Register scratch1, Register scratch2, Label* miss_label) { | 
| 554                                            Register name_reg, |  | 
| 555                                            Register value_reg, |  | 
| 556                                            Register scratch1, |  | 
| 557                                            Register scratch2, |  | 
| 558                                            Label* miss_label) { |  | 
| 559   // a0 : value | 479   // a0 : value | 
| 560   Label exit; | 480   Label exit; | 
| 561 | 481 | 
| 562   // Stub never generated for non-global objects that require access | 482   // Stub never generated for non-global objects that require access | 
| 563   // checks. | 483   // checks. | 
| 564   ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); | 484   ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); | 
| 565 | 485 | 
| 566   FieldIndex index = lookup->GetFieldIndex(); | 486   FieldIndex index = lookup->GetFieldIndex(); | 
| 567 | 487 | 
| 568   Representation representation = lookup->representation(); | 488   Representation representation = lookup->representation(); | 
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 670   } | 590   } | 
| 671 | 591 | 
| 672   // Return the value (register v0). | 592   // Return the value (register v0). | 
| 673   ASSERT(value_reg.is(a0)); | 593   ASSERT(value_reg.is(a0)); | 
| 674   __ bind(&exit); | 594   __ bind(&exit); | 
| 675   __ Ret(USE_DELAY_SLOT); | 595   __ Ret(USE_DELAY_SLOT); | 
| 676   __ mov(v0, a0); | 596   __ mov(v0, a0); | 
| 677 } | 597 } | 
| 678 | 598 | 
| 679 | 599 | 
| 680 void StoreStubCompiler::GenerateRestoreName(MacroAssembler* masm, | 600 void NamedStoreHandlerCompiler::GenerateRestoreName(MacroAssembler* masm, | 
| 681                                             Label* label, | 601                                                     Label* label, | 
| 682                                             Handle<Name> name) { | 602                                                     Handle<Name> name) { | 
| 683   if (!label->is_unused()) { | 603   if (!label->is_unused()) { | 
| 684     __ bind(label); | 604     __ bind(label); | 
| 685     __ li(this->name(), Operand(name)); | 605     __ li(this->name(), Operand(name)); | 
| 686   } | 606   } | 
| 687 } | 607 } | 
| 688 | 608 | 
| 689 | 609 | 
| 690 static void PushInterceptorArguments(MacroAssembler* masm, | 610 static void PushInterceptorArguments(MacroAssembler* masm, | 
| 691                                      Register receiver, | 611                                      Register receiver, | 
| 692                                      Register holder, | 612                                      Register holder, | 
| (...skipping 21 matching lines...) Expand all  Loading... | 
| 714     Handle<JSObject> holder_obj, | 634     Handle<JSObject> holder_obj, | 
| 715     IC::UtilityId id) { | 635     IC::UtilityId id) { | 
| 716   PushInterceptorArguments(masm, receiver, holder, name, holder_obj); | 636   PushInterceptorArguments(masm, receiver, holder, name, holder_obj); | 
| 717   __ CallExternalReference( | 637   __ CallExternalReference( | 
| 718       ExternalReference(IC_Utility(id), masm->isolate()), | 638       ExternalReference(IC_Utility(id), masm->isolate()), | 
| 719       StubCache::kInterceptorArgsLength); | 639       StubCache::kInterceptorArgsLength); | 
| 720 } | 640 } | 
| 721 | 641 | 
| 722 | 642 | 
| 723 // Generate call to api function. | 643 // Generate call to api function. | 
| 724 void StubCompiler::GenerateFastApiCall(MacroAssembler* masm, | 644 void PropertyHandlerCompiler::GenerateFastApiCall( | 
| 725                                        const CallOptimization& optimization, | 645     MacroAssembler* masm, const CallOptimization& optimization, | 
| 726                                        Handle<Map> receiver_map, | 646     Handle<Map> receiver_map, Register receiver, Register scratch_in, | 
| 727                                        Register receiver, | 647     bool is_store, int argc, Register* values) { | 
| 728                                        Register scratch_in, |  | 
| 729                                        bool is_store, |  | 
| 730                                        int argc, |  | 
| 731                                        Register* values) { |  | 
| 732   ASSERT(!receiver.is(scratch_in)); | 648   ASSERT(!receiver.is(scratch_in)); | 
| 733   // Preparing to push, adjust sp. | 649   // Preparing to push, adjust sp. | 
| 734   __ Dsubu(sp, sp, Operand((argc + 1) * kPointerSize)); | 650   __ Dsubu(sp, sp, Operand((argc + 1) * kPointerSize)); | 
| 735   __ sd(receiver, MemOperand(sp, argc * kPointerSize));  // Push receiver. | 651   __ sd(receiver, MemOperand(sp, argc * kPointerSize));  // Push receiver. | 
| 736   // Write the arguments to stack frame. | 652   // Write the arguments to stack frame. | 
| 737   for (int i = 0; i < argc; i++) { | 653   for (int i = 0; i < argc; i++) { | 
| 738     Register arg = values[argc-1-i]; | 654     Register arg = values[argc-1-i]; | 
| 739     ASSERT(!receiver.is(arg)); | 655     ASSERT(!receiver.is(arg)); | 
| 740     ASSERT(!scratch_in.is(arg)); | 656     ASSERT(!scratch_in.is(arg)); | 
| 741     __ sd(arg, MemOperand(sp, (argc-1-i) * kPointerSize));  // Push arg. | 657     __ sd(arg, MemOperand(sp, (argc-1-i) * kPointerSize));  // Push arg. | 
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 793                         type, | 709                         type, | 
| 794                         masm->isolate()); | 710                         masm->isolate()); | 
| 795   __ li(api_function_address, Operand(ref)); | 711   __ li(api_function_address, Operand(ref)); | 
| 796 | 712 | 
| 797   // Jump to stub. | 713   // Jump to stub. | 
| 798   CallApiFunctionStub stub(isolate, is_store, call_data_undefined, argc); | 714   CallApiFunctionStub stub(isolate, is_store, call_data_undefined, argc); | 
| 799   __ TailCallStub(&stub); | 715   __ TailCallStub(&stub); | 
| 800 } | 716 } | 
| 801 | 717 | 
| 802 | 718 | 
| 803 void StubCompiler::GenerateTailCall(MacroAssembler* masm, Handle<Code> code) { | 719 void PropertyAccessCompiler::GenerateTailCall(MacroAssembler* masm, | 
|  | 720                                               Handle<Code> code) { | 
| 804   __ Jump(code, RelocInfo::CODE_TARGET); | 721   __ Jump(code, RelocInfo::CODE_TARGET); | 
| 805 } | 722 } | 
| 806 | 723 | 
| 807 | 724 | 
| 808 #undef __ | 725 #undef __ | 
| 809 #define __ ACCESS_MASM(masm()) | 726 #define __ ACCESS_MASM(masm()) | 
| 810 | 727 | 
| 811 | 728 | 
| 812 Register StubCompiler::CheckPrototypes(Handle<HeapType> type, | 729 Register PropertyHandlerCompiler::CheckPrototypes( | 
| 813                                        Register object_reg, | 730     Handle<HeapType> type, Register object_reg, Handle<JSObject> holder, | 
| 814                                        Handle<JSObject> holder, | 731     Register holder_reg, Register scratch1, Register scratch2, | 
| 815                                        Register holder_reg, | 732     Handle<Name> name, Label* miss, PrototypeCheckType check) { | 
| 816                                        Register scratch1, |  | 
| 817                                        Register scratch2, |  | 
| 818                                        Handle<Name> name, |  | 
| 819                                        Label* miss, |  | 
| 820                                        PrototypeCheckType check) { |  | 
| 821   Handle<Map> receiver_map(IC::TypeToMap(*type, isolate())); | 733   Handle<Map> receiver_map(IC::TypeToMap(*type, isolate())); | 
| 822 | 734 | 
| 823   // Make sure there's no overlap between holder and object registers. | 735   // Make sure there's no overlap between holder and object registers. | 
| 824   ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); | 736   ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); | 
| 825   ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) | 737   ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) | 
| 826          && !scratch2.is(scratch1)); | 738          && !scratch2.is(scratch1)); | 
| 827 | 739 | 
| 828   // Keep track of the current object in register reg. | 740   // Keep track of the current object in register reg. | 
| 829   Register reg = object_reg; | 741   Register reg = object_reg; | 
| 830   int depth = 0; | 742   int depth = 0; | 
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 917          !current_map->is_access_check_needed()); | 829          !current_map->is_access_check_needed()); | 
| 918   if (current_map->IsJSGlobalProxyMap()) { | 830   if (current_map->IsJSGlobalProxyMap()) { | 
| 919     __ CheckAccessGlobalProxy(reg, scratch1, miss); | 831     __ CheckAccessGlobalProxy(reg, scratch1, miss); | 
| 920   } | 832   } | 
| 921 | 833 | 
| 922   // Return the register containing the holder. | 834   // Return the register containing the holder. | 
| 923   return reg; | 835   return reg; | 
| 924 } | 836 } | 
| 925 | 837 | 
| 926 | 838 | 
| 927 void LoadStubCompiler::HandlerFrontendFooter(Handle<Name> name, Label* miss) { | 839 void NamedLoadHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) { | 
| 928   if (!miss->is_unused()) { | 840   if (!miss->is_unused()) { | 
| 929     Label success; | 841     Label success; | 
| 930     __ Branch(&success); | 842     __ Branch(&success); | 
| 931     __ bind(miss); | 843     __ bind(miss); | 
| 932     TailCallBuiltin(masm(), MissBuiltin(kind())); | 844     TailCallBuiltin(masm(), MissBuiltin(kind())); | 
| 933     __ bind(&success); | 845     __ bind(&success); | 
| 934   } | 846   } | 
| 935 } | 847 } | 
| 936 | 848 | 
| 937 | 849 | 
| 938 void StoreStubCompiler::HandlerFrontendFooter(Handle<Name> name, Label* miss) { | 850 void NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) { | 
| 939   if (!miss->is_unused()) { | 851   if (!miss->is_unused()) { | 
| 940     Label success; | 852     Label success; | 
| 941     __ Branch(&success); | 853     __ Branch(&success); | 
| 942     GenerateRestoreName(masm(), miss, name); | 854     GenerateRestoreName(masm(), miss, name); | 
| 943     TailCallBuiltin(masm(), MissBuiltin(kind())); | 855     TailCallBuiltin(masm(), MissBuiltin(kind())); | 
| 944     __ bind(&success); | 856     __ bind(&success); | 
| 945   } | 857   } | 
| 946 } | 858 } | 
| 947 | 859 | 
| 948 | 860 | 
| 949 Register LoadStubCompiler::CallbackHandlerFrontend( | 861 Register NamedLoadHandlerCompiler::CallbackFrontend(Handle<HeapType> type, | 
| 950     Handle<HeapType> type, | 862                                                     Register object_reg, | 
| 951     Register object_reg, | 863                                                     Handle<JSObject> holder, | 
| 952     Handle<JSObject> holder, | 864                                                     Handle<Name> name, | 
| 953     Handle<Name> name, | 865                                                     Handle<Object> callback) { | 
| 954     Handle<Object> callback) { |  | 
| 955   Label miss; | 866   Label miss; | 
| 956 | 867 | 
| 957   Register reg = HandlerFrontendHeader(type, object_reg, holder, name, &miss); | 868   Register reg = FrontendHeader(type, object_reg, holder, name, &miss); | 
| 958 | 869 | 
| 959   if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) { | 870   if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) { | 
| 960     ASSERT(!reg.is(scratch2())); | 871     ASSERT(!reg.is(scratch2())); | 
| 961     ASSERT(!reg.is(scratch3())); | 872     ASSERT(!reg.is(scratch3())); | 
| 962     ASSERT(!reg.is(scratch4())); | 873     ASSERT(!reg.is(scratch4())); | 
| 963 | 874 | 
| 964     // Load the properties dictionary. | 875     // Load the properties dictionary. | 
| 965     Register dictionary = scratch4(); | 876     Register dictionary = scratch4(); | 
| 966     __ ld(dictionary, FieldMemOperand(reg, JSObject::kPropertiesOffset)); | 877     __ ld(dictionary, FieldMemOperand(reg, JSObject::kPropertiesOffset)); | 
| 967 | 878 | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
| 979     // If probing finds an entry in the dictionary, scratch3 contains the | 890     // If probing finds an entry in the dictionary, scratch3 contains the | 
| 980     // pointer into the dictionary. Check that the value is the callback. | 891     // pointer into the dictionary. Check that the value is the callback. | 
| 981     Register pointer = scratch3(); | 892     Register pointer = scratch3(); | 
| 982     const int kElementsStartOffset = NameDictionary::kHeaderSize + | 893     const int kElementsStartOffset = NameDictionary::kHeaderSize + | 
| 983         NameDictionary::kElementsStartIndex * kPointerSize; | 894         NameDictionary::kElementsStartIndex * kPointerSize; | 
| 984     const int kValueOffset = kElementsStartOffset + kPointerSize; | 895     const int kValueOffset = kElementsStartOffset + kPointerSize; | 
| 985     __ ld(scratch2(), FieldMemOperand(pointer, kValueOffset)); | 896     __ ld(scratch2(), FieldMemOperand(pointer, kValueOffset)); | 
| 986     __ Branch(&miss, ne, scratch2(), Operand(callback)); | 897     __ Branch(&miss, ne, scratch2(), Operand(callback)); | 
| 987   } | 898   } | 
| 988 | 899 | 
| 989   HandlerFrontendFooter(name, &miss); | 900   FrontendFooter(name, &miss); | 
| 990   return reg; | 901   return reg; | 
| 991 } | 902 } | 
| 992 | 903 | 
| 993 | 904 | 
| 994 void LoadStubCompiler::GenerateLoadField(Register reg, | 905 void NamedLoadHandlerCompiler::GenerateLoadField( | 
| 995                                          Handle<JSObject> holder, | 906     Register reg, Handle<JSObject> holder, FieldIndex field, | 
| 996                                          FieldIndex field, | 907     Representation representation) { | 
| 997                                          Representation representation) { |  | 
| 998   if (!reg.is(receiver())) __ mov(receiver(), reg); | 908   if (!reg.is(receiver())) __ mov(receiver(), reg); | 
| 999   LoadFieldStub stub(isolate(), field); | 909   LoadFieldStub stub(isolate(), field); | 
| 1000   GenerateTailCall(masm(), stub.GetCode()); | 910   GenerateTailCall(masm(), stub.GetCode()); | 
| 1001 } | 911 } | 
| 1002 | 912 | 
| 1003 | 913 | 
| 1004 void LoadStubCompiler::GenerateLoadConstant(Handle<Object> value) { | 914 void NamedLoadHandlerCompiler::GenerateLoadConstant(Handle<Object> value) { | 
| 1005   // Return the constant value. | 915   // Return the constant value. | 
| 1006   __ li(v0, value); | 916   __ li(v0, value); | 
| 1007   __ Ret(); | 917   __ Ret(); | 
| 1008 } | 918 } | 
| 1009 | 919 | 
| 1010 | 920 | 
| 1011 void LoadStubCompiler::GenerateLoadCallback( | 921 void NamedLoadHandlerCompiler::GenerateLoadCallback( | 
| 1012     Register reg, | 922     Register reg, Handle<ExecutableAccessorInfo> callback) { | 
| 1013     Handle<ExecutableAccessorInfo> callback) { |  | 
| 1014   // Build AccessorInfo::args_ list on the stack and push property name below | 923   // Build AccessorInfo::args_ list on the stack and push property name below | 
| 1015   // the exit frame to make GC aware of them and store pointers to them. | 924   // the exit frame to make GC aware of them and store pointers to them. | 
| 1016   STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == 0); | 925   STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == 0); | 
| 1017   STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 1); | 926   STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 1); | 
| 1018   STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == 2); | 927   STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == 2); | 
| 1019   STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 3); | 928   STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 3); | 
| 1020   STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == 4); | 929   STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == 4); | 
| 1021   STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 5); | 930   STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 5); | 
| 1022   STATIC_ASSERT(PropertyCallbackArguments::kArgsLength == 6); | 931   STATIC_ASSERT(PropertyCallbackArguments::kArgsLength == 6); | 
| 1023   ASSERT(!scratch2().is(reg)); | 932   ASSERT(!scratch2().is(reg)); | 
| (...skipping 27 matching lines...) Expand all  Loading... | 
| 1051   ApiFunction fun(getter_address); | 960   ApiFunction fun(getter_address); | 
| 1052   ExternalReference::Type type = ExternalReference::DIRECT_GETTER_CALL; | 961   ExternalReference::Type type = ExternalReference::DIRECT_GETTER_CALL; | 
| 1053   ExternalReference ref = ExternalReference(&fun, type, isolate()); | 962   ExternalReference ref = ExternalReference(&fun, type, isolate()); | 
| 1054   __ li(getter_address_reg, Operand(ref)); | 963   __ li(getter_address_reg, Operand(ref)); | 
| 1055 | 964 | 
| 1056   CallApiGetterStub stub(isolate()); | 965   CallApiGetterStub stub(isolate()); | 
| 1057   __ TailCallStub(&stub); | 966   __ TailCallStub(&stub); | 
| 1058 } | 967 } | 
| 1059 | 968 | 
| 1060 | 969 | 
| 1061 void LoadStubCompiler::GenerateLoadInterceptor( | 970 void NamedLoadHandlerCompiler::GenerateLoadInterceptor( | 
| 1062     Register holder_reg, | 971     Register holder_reg, Handle<Object> object, | 
| 1063     Handle<Object> object, | 972     Handle<JSObject> interceptor_holder, LookupResult* lookup, | 
| 1064     Handle<JSObject> interceptor_holder, |  | 
| 1065     LookupResult* lookup, |  | 
| 1066     Handle<Name> name) { | 973     Handle<Name> name) { | 
| 1067   ASSERT(interceptor_holder->HasNamedInterceptor()); | 974   ASSERT(interceptor_holder->HasNamedInterceptor()); | 
| 1068   ASSERT(!interceptor_holder->GetNamedInterceptor()->getter()->IsUndefined()); | 975   ASSERT(!interceptor_holder->GetNamedInterceptor()->getter()->IsUndefined()); | 
| 1069 | 976 | 
| 1070   // So far the most popular follow ups for interceptor loads are FIELD | 977   // So far the most popular follow ups for interceptor loads are FIELD | 
| 1071   // and CALLBACKS, so inline only them, other cases may be added | 978   // and CALLBACKS, so inline only them, other cases may be added | 
| 1072   // later. | 979   // later. | 
| 1073   bool compile_followup_inline = false; | 980   bool compile_followup_inline = false; | 
| 1074   if (lookup->IsFound() && lookup->IsCacheable()) { | 981   if (lookup->IsFound() && lookup->IsCacheable()) { | 
| 1075     if (lookup->IsField()) { | 982     if (lookup->IsField()) { | 
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1136     PushInterceptorArguments(masm(), receiver(), holder_reg, | 1043     PushInterceptorArguments(masm(), receiver(), holder_reg, | 
| 1137                              this->name(), interceptor_holder); | 1044                              this->name(), interceptor_holder); | 
| 1138 | 1045 | 
| 1139     ExternalReference ref = ExternalReference( | 1046     ExternalReference ref = ExternalReference( | 
| 1140         IC_Utility(IC::kLoadPropertyWithInterceptor), isolate()); | 1047         IC_Utility(IC::kLoadPropertyWithInterceptor), isolate()); | 
| 1141     __ TailCallExternalReference(ref, StubCache::kInterceptorArgsLength, 1); | 1048     __ TailCallExternalReference(ref, StubCache::kInterceptorArgsLength, 1); | 
| 1142   } | 1049   } | 
| 1143 } | 1050 } | 
| 1144 | 1051 | 
| 1145 | 1052 | 
| 1146 Handle<Code> StoreStubCompiler::CompileStoreCallback( | 1053 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback( | 
| 1147     Handle<JSObject> object, | 1054     Handle<JSObject> object, Handle<JSObject> holder, Handle<Name> name, | 
| 1148     Handle<JSObject> holder, |  | 
| 1149     Handle<Name> name, |  | 
| 1150     Handle<ExecutableAccessorInfo> callback) { | 1055     Handle<ExecutableAccessorInfo> callback) { | 
| 1151   Register holder_reg = HandlerFrontend( | 1056   Register holder_reg = | 
| 1152       IC::CurrentTypeOf(object, isolate()), receiver(), holder, name); | 1057       Frontend(IC::CurrentTypeOf(object, isolate()), receiver(), holder, name); | 
| 1153 | 1058 | 
| 1154   // Stub never generated for non-global objects that require access | 1059   // Stub never generated for non-global objects that require access | 
| 1155   // checks. | 1060   // checks. | 
| 1156   ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); | 1061   ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); | 
| 1157 | 1062 | 
| 1158   __ Push(receiver(), holder_reg);  // Receiver. | 1063   __ Push(receiver(), holder_reg);  // Receiver. | 
| 1159   __ li(at, Operand(callback));  // Callback info. | 1064   __ li(at, Operand(callback));  // Callback info. | 
| 1160   __ push(at); | 1065   __ push(at); | 
| 1161   __ li(at, Operand(name)); | 1066   __ li(at, Operand(name)); | 
| 1162   __ Push(at, value()); | 1067   __ Push(at, value()); | 
| 1163 | 1068 | 
| 1164   // Do tail-call to the runtime system. | 1069   // Do tail-call to the runtime system. | 
| 1165   ExternalReference store_callback_property = | 1070   ExternalReference store_callback_property = | 
| 1166       ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate()); | 1071       ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate()); | 
| 1167   __ TailCallExternalReference(store_callback_property, 5, 1); | 1072   __ TailCallExternalReference(store_callback_property, 5, 1); | 
| 1168 | 1073 | 
| 1169   // Return the generated code. | 1074   // Return the generated code. | 
| 1170   return GetCode(kind(), Code::FAST, name); | 1075   return GetCode(kind(), Code::FAST, name); | 
| 1171 } | 1076 } | 
| 1172 | 1077 | 
| 1173 | 1078 | 
| 1174 #undef __ | 1079 #undef __ | 
| 1175 #define __ ACCESS_MASM(masm) | 1080 #define __ ACCESS_MASM(masm) | 
| 1176 | 1081 | 
| 1177 | 1082 | 
| 1178 void StoreStubCompiler::GenerateStoreViaSetter( | 1083 void NamedStoreHandlerCompiler::GenerateStoreViaSetter( | 
| 1179     MacroAssembler* masm, | 1084     MacroAssembler* masm, Handle<HeapType> type, Register receiver, | 
| 1180     Handle<HeapType> type, |  | 
| 1181     Register receiver, |  | 
| 1182     Handle<JSFunction> setter) { | 1085     Handle<JSFunction> setter) { | 
| 1183   // ----------- S t a t e ------------- | 1086   // ----------- S t a t e ------------- | 
| 1184   //  -- ra    : return address | 1087   //  -- ra    : return address | 
| 1185   // ----------------------------------- | 1088   // ----------------------------------- | 
| 1186   { | 1089   { | 
| 1187     FrameScope scope(masm, StackFrame::INTERNAL); | 1090     FrameScope scope(masm, StackFrame::INTERNAL); | 
| 1188 | 1091 | 
| 1189     // Save value register, so we can restore it later. | 1092     // Save value register, so we can restore it later. | 
| 1190     __ push(value()); | 1093     __ push(value()); | 
| 1191 | 1094 | 
| (...skipping 22 matching lines...) Expand all  Loading... | 
| 1214     __ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 1117     __ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 
| 1215   } | 1118   } | 
| 1216   __ Ret(); | 1119   __ Ret(); | 
| 1217 } | 1120 } | 
| 1218 | 1121 | 
| 1219 | 1122 | 
| 1220 #undef __ | 1123 #undef __ | 
| 1221 #define __ ACCESS_MASM(masm()) | 1124 #define __ ACCESS_MASM(masm()) | 
| 1222 | 1125 | 
| 1223 | 1126 | 
| 1224 Handle<Code> StoreStubCompiler::CompileStoreInterceptor( | 1127 Handle<Code> NamedStoreHandlerCompiler::CompileStoreInterceptor( | 
| 1225     Handle<JSObject> object, | 1128     Handle<JSObject> object, Handle<Name> name) { | 
| 1226     Handle<Name> name) { |  | 
| 1227   __ Push(receiver(), this->name(), value()); | 1129   __ Push(receiver(), this->name(), value()); | 
| 1228 | 1130 | 
| 1229   // Do tail-call to the runtime system. | 1131   // Do tail-call to the runtime system. | 
| 1230   ExternalReference store_ic_property = | 1132   ExternalReference store_ic_property = | 
| 1231       ExternalReference(IC_Utility(IC::kStoreInterceptorProperty), isolate()); | 1133       ExternalReference(IC_Utility(IC::kStoreInterceptorProperty), isolate()); | 
| 1232   __ TailCallExternalReference(store_ic_property, 3, 1); | 1134   __ TailCallExternalReference(store_ic_property, 3, 1); | 
| 1233 | 1135 | 
| 1234   // Return the generated code. | 1136   // Return the generated code. | 
| 1235   return GetCode(kind(), Code::FAST, name); | 1137   return GetCode(kind(), Code::FAST, name); | 
| 1236 } | 1138 } | 
| 1237 | 1139 | 
| 1238 | 1140 | 
| 1239 Handle<Code> LoadStubCompiler::CompileLoadNonexistent(Handle<HeapType> type, | 1141 Handle<Code> NamedLoadHandlerCompiler::CompileLoadNonexistent( | 
| 1240                                                       Handle<JSObject> last, | 1142     Handle<HeapType> type, Handle<JSObject> last, Handle<Name> name) { | 
| 1241                                                       Handle<Name> name) { | 1143   NonexistentFrontend(type, last, name); | 
| 1242   NonexistentHandlerFrontend(type, last, name); |  | 
| 1243 | 1144 | 
| 1244   // Return undefined if maps of the full prototype chain is still the same. | 1145   // Return undefined if maps of the full prototype chain is still the same. | 
| 1245   __ LoadRoot(v0, Heap::kUndefinedValueRootIndex); | 1146   __ LoadRoot(v0, Heap::kUndefinedValueRootIndex); | 
| 1246   __ Ret(); | 1147   __ Ret(); | 
| 1247 | 1148 | 
| 1248   // Return the generated code. | 1149   // Return the generated code. | 
| 1249   return GetCode(kind(), Code::FAST, name); | 1150   return GetCode(kind(), Code::FAST, name); | 
| 1250 } | 1151 } | 
| 1251 | 1152 | 
| 1252 | 1153 | 
| 1253 Register* LoadStubCompiler::registers() { | 1154 Register* PropertyAccessCompiler::load_calling_convention() { | 
| 1254   // receiver, name, scratch1, scratch2, scratch3, scratch4. | 1155   // receiver, name, scratch1, scratch2, scratch3, scratch4. | 
| 1255   Register receiver = LoadIC::ReceiverRegister(); | 1156   Register receiver = LoadIC::ReceiverRegister(); | 
| 1256   Register name = LoadIC::NameRegister(); | 1157   Register name = LoadIC::NameRegister(); | 
| 1257   static Register registers[] = { receiver, name, a3, a0, a4, a5 }; | 1158   static Register registers[] = { receiver, name, a3, a0, a4, a5 }; | 
| 1258   return registers; | 1159   return registers; | 
| 1259 } | 1160 } | 
| 1260 | 1161 | 
| 1261 | 1162 | 
| 1262 Register* KeyedLoadStubCompiler::registers() { | 1163 Register* PropertyAccessCompiler::store_calling_convention() { | 
| 1263   // receiver, name, scratch1, scratch2, scratch3, scratch4. |  | 
| 1264   Register receiver = LoadIC::ReceiverRegister(); |  | 
| 1265   Register name = LoadIC::NameRegister(); |  | 
| 1266   static Register registers[] = { receiver, name, a3, a0, a4, a5 }; |  | 
| 1267   return registers; |  | 
| 1268 } |  | 
| 1269 |  | 
| 1270 |  | 
| 1271 Register StoreStubCompiler::value() { |  | 
| 1272   return StoreIC::ValueRegister(); |  | 
| 1273 } |  | 
| 1274 |  | 
| 1275 |  | 
| 1276 Register* StoreStubCompiler::registers() { |  | 
| 1277   // receiver, name, scratch1, scratch2, scratch3. | 1164   // receiver, name, scratch1, scratch2, scratch3. | 
| 1278   Register receiver = StoreIC::ReceiverRegister(); | 1165   Register receiver = StoreIC::ReceiverRegister(); | 
| 1279   Register name = StoreIC::NameRegister(); | 1166   Register name = StoreIC::NameRegister(); | 
| 1280   static Register registers[] = { receiver, name, a3, a4, a5 }; | 1167   static Register registers[] = { receiver, name, a3, a4, a5 }; | 
| 1281   return registers; | 1168   return registers; | 
| 1282 } | 1169 } | 
| 1283 | 1170 | 
| 1284 | 1171 | 
| 1285 Register* KeyedStoreStubCompiler::registers() { | 1172 Register* PropertyAccessCompiler::keyed_store_calling_convention() { | 
| 1286   // receiver, name, scratch1/map, scratch2, scratch3. | 1173   // receiver, name, scratch1/map, scratch2, scratch3. | 
| 1287   Register receiver = KeyedStoreIC::ReceiverRegister(); | 1174   Register receiver = KeyedStoreIC::ReceiverRegister(); | 
| 1288   Register name = KeyedStoreIC::NameRegister(); | 1175   Register name = KeyedStoreIC::NameRegister(); | 
| 1289   Register map = KeyedStoreIC::MapRegister(); | 1176   Register map = KeyedStoreIC::MapRegister(); | 
| 1290   static Register registers[] = { receiver, name, map, a4, a5 }; | 1177   static Register registers[] = { receiver, name, map, a4, a5 }; | 
| 1291   return registers; | 1178   return registers; | 
| 1292 } | 1179 } | 
| 1293 | 1180 | 
| 1294 | 1181 | 
|  | 1182 Register NamedStoreHandlerCompiler::value() { return StoreIC::ValueRegister(); } | 
|  | 1183 | 
|  | 1184 | 
| 1295 #undef __ | 1185 #undef __ | 
| 1296 #define __ ACCESS_MASM(masm) | 1186 #define __ ACCESS_MASM(masm) | 
| 1297 | 1187 | 
| 1298 | 1188 | 
| 1299 void LoadStubCompiler::GenerateLoadViaGetter(MacroAssembler* masm, | 1189 void NamedLoadHandlerCompiler::GenerateLoadViaGetter( | 
| 1300                                              Handle<HeapType> type, | 1190     MacroAssembler* masm, Handle<HeapType> type, Register receiver, | 
| 1301                                              Register receiver, | 1191     Handle<JSFunction> getter) { | 
| 1302                                              Handle<JSFunction> getter) { |  | 
| 1303   // ----------- S t a t e ------------- | 1192   // ----------- S t a t e ------------- | 
| 1304   //  -- a0    : receiver | 1193   //  -- a0    : receiver | 
| 1305   //  -- a2    : name | 1194   //  -- a2    : name | 
| 1306   //  -- ra    : return address | 1195   //  -- ra    : return address | 
| 1307   // ----------------------------------- | 1196   // ----------------------------------- | 
| 1308   { | 1197   { | 
| 1309     FrameScope scope(masm, StackFrame::INTERNAL); | 1198     FrameScope scope(masm, StackFrame::INTERNAL); | 
| 1310 | 1199 | 
| 1311     if (!getter.is_null()) { | 1200     if (!getter.is_null()) { | 
| 1312       // Call the JavaScript getter with the receiver on the stack. | 1201       // Call the JavaScript getter with the receiver on the stack. | 
| (...skipping 17 matching lines...) Expand all  Loading... | 
| 1330     __ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 1219     __ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 
| 1331   } | 1220   } | 
| 1332   __ Ret(); | 1221   __ Ret(); | 
| 1333 } | 1222 } | 
| 1334 | 1223 | 
| 1335 | 1224 | 
| 1336 #undef __ | 1225 #undef __ | 
| 1337 #define __ ACCESS_MASM(masm()) | 1226 #define __ ACCESS_MASM(masm()) | 
| 1338 | 1227 | 
| 1339 | 1228 | 
| 1340 Handle<Code> LoadStubCompiler::CompileLoadGlobal( | 1229 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal( | 
| 1341     Handle<HeapType> type, | 1230     Handle<HeapType> type, Handle<GlobalObject> global, | 
| 1342     Handle<GlobalObject> global, | 1231     Handle<PropertyCell> cell, Handle<Name> name, bool is_dont_delete) { | 
| 1343     Handle<PropertyCell> cell, |  | 
| 1344     Handle<Name> name, |  | 
| 1345     bool is_dont_delete) { |  | 
| 1346   Label miss; | 1232   Label miss; | 
| 1347 | 1233 | 
| 1348   HandlerFrontendHeader(type, receiver(), global, name, &miss); | 1234   FrontendHeader(type, receiver(), global, name, &miss); | 
| 1349 | 1235 | 
| 1350   // Get the value from the cell. | 1236   // Get the value from the cell. | 
| 1351   __ li(a3, Operand(cell)); | 1237   __ li(a3, Operand(cell)); | 
| 1352   __ ld(a4, FieldMemOperand(a3, Cell::kValueOffset)); | 1238   __ ld(a4, FieldMemOperand(a3, Cell::kValueOffset)); | 
| 1353 | 1239 | 
| 1354   // Check for deleted property if property can actually be deleted. | 1240   // Check for deleted property if property can actually be deleted. | 
| 1355   if (!is_dont_delete) { | 1241   if (!is_dont_delete) { | 
| 1356     __ LoadRoot(at, Heap::kTheHoleValueRootIndex); | 1242     __ LoadRoot(at, Heap::kTheHoleValueRootIndex); | 
| 1357     __ Branch(&miss, eq, a4, Operand(at)); | 1243     __ Branch(&miss, eq, a4, Operand(at)); | 
| 1358   } | 1244   } | 
| 1359 | 1245 | 
| 1360   Counters* counters = isolate()->counters(); | 1246   Counters* counters = isolate()->counters(); | 
| 1361   __ IncrementCounter(counters->named_load_global_stub(), 1, a1, a3); | 1247   __ IncrementCounter(counters->named_load_global_stub(), 1, a1, a3); | 
| 1362   __ Ret(USE_DELAY_SLOT); | 1248   __ Ret(USE_DELAY_SLOT); | 
| 1363   __ mov(v0, a4); | 1249   __ mov(v0, a4); | 
| 1364 | 1250 | 
| 1365   HandlerFrontendFooter(name, &miss); | 1251   FrontendFooter(name, &miss); | 
| 1366 | 1252 | 
| 1367   // Return the generated code. | 1253   // Return the generated code. | 
| 1368   return GetCode(kind(), Code::NORMAL, name); | 1254   return GetCode(kind(), Code::NORMAL, name); | 
| 1369 } | 1255 } | 
| 1370 | 1256 | 
| 1371 | 1257 | 
| 1372 Handle<Code> BaseLoadStoreStubCompiler::CompilePolymorphicIC( | 1258 Handle<Code> PropertyICCompiler::CompilePolymorphic(TypeHandleList* types, | 
| 1373     TypeHandleList* types, | 1259                                                     CodeHandleList* handlers, | 
| 1374     CodeHandleList* handlers, | 1260                                                     Handle<Name> name, | 
| 1375     Handle<Name> name, | 1261                                                     Code::StubType type, | 
| 1376     Code::StubType type, | 1262                                                     IcCheckType check) { | 
| 1377     IcCheckType check) { |  | 
| 1378   Label miss; | 1263   Label miss; | 
| 1379 | 1264 | 
| 1380   if (check == PROPERTY && | 1265   if (check == PROPERTY && | 
| 1381       (kind() == Code::KEYED_LOAD_IC || kind() == Code::KEYED_STORE_IC)) { | 1266       (kind() == Code::KEYED_LOAD_IC || kind() == Code::KEYED_STORE_IC)) { | 
| 1382     __ Branch(&miss, ne, this->name(), Operand(name)); | 1267     __ Branch(&miss, ne, this->name(), Operand(name)); | 
| 1383   } | 1268   } | 
| 1384 | 1269 | 
| 1385   Label number_case; | 1270   Label number_case; | 
| 1386   Register match = scratch2(); | 1271   Register match = scratch2(); | 
| 1387   Label* smi_target = IncludesNumberType(types) ? &number_case : &miss; | 1272   Label* smi_target = IncludesNumberType(types) ? &number_case : &miss; | 
| (...skipping 24 matching lines...) Expand all  Loading... | 
| 1412     } | 1297     } | 
| 1413   } | 1298   } | 
| 1414   ASSERT(number_of_handled_maps != 0); | 1299   ASSERT(number_of_handled_maps != 0); | 
| 1415 | 1300 | 
| 1416   __ bind(&miss); | 1301   __ bind(&miss); | 
| 1417   TailCallBuiltin(masm(), MissBuiltin(kind())); | 1302   TailCallBuiltin(masm(), MissBuiltin(kind())); | 
| 1418 | 1303 | 
| 1419   // Return the generated code. | 1304   // Return the generated code. | 
| 1420   InlineCacheState state = | 1305   InlineCacheState state = | 
| 1421       number_of_handled_maps > 1 ? POLYMORPHIC : MONOMORPHIC; | 1306       number_of_handled_maps > 1 ? POLYMORPHIC : MONOMORPHIC; | 
| 1422   return GetICCode(kind(), type, name, state); | 1307   return GetCode(kind(), type, name, state); | 
| 1423 } | 1308 } | 
| 1424 | 1309 | 
| 1425 | 1310 | 
| 1426 void StoreStubCompiler::GenerateStoreArrayLength() { | 1311 void NamedStoreHandlerCompiler::GenerateStoreArrayLength() { | 
| 1427   // Prepare tail call to StoreIC_ArrayLength. | 1312   // Prepare tail call to StoreIC_ArrayLength. | 
| 1428   __ Push(receiver(), value()); | 1313   __ Push(receiver(), value()); | 
| 1429 | 1314 | 
| 1430   ExternalReference ref = | 1315   ExternalReference ref = | 
| 1431       ExternalReference(IC_Utility(IC::kStoreIC_ArrayLength), | 1316       ExternalReference(IC_Utility(IC::kStoreIC_ArrayLength), | 
| 1432                         masm()->isolate()); | 1317                         masm()->isolate()); | 
| 1433   __ TailCallExternalReference(ref, 2, 1); | 1318   __ TailCallExternalReference(ref, 2, 1); | 
| 1434 } | 1319 } | 
| 1435 | 1320 | 
| 1436 | 1321 | 
| 1437 Handle<Code> KeyedStoreStubCompiler::CompileStorePolymorphic( | 1322 Handle<Code> PropertyICCompiler::CompileIndexedStorePolymorphic( | 
| 1438     MapHandleList* receiver_maps, | 1323     MapHandleList* receiver_maps, CodeHandleList* handler_stubs, | 
| 1439     CodeHandleList* handler_stubs, |  | 
| 1440     MapHandleList* transitioned_maps) { | 1324     MapHandleList* transitioned_maps) { | 
| 1441   Label miss; | 1325   Label miss; | 
| 1442   __ JumpIfSmi(receiver(), &miss); | 1326   __ JumpIfSmi(receiver(), &miss); | 
| 1443 | 1327 | 
| 1444   int receiver_count = receiver_maps->length(); | 1328   int receiver_count = receiver_maps->length(); | 
| 1445   __ ld(scratch1(), FieldMemOperand(receiver(), HeapObject::kMapOffset)); | 1329   __ ld(scratch1(), FieldMemOperand(receiver(), HeapObject::kMapOffset)); | 
| 1446   for (int i = 0; i < receiver_count; ++i) { | 1330   for (int i = 0; i < receiver_count; ++i) { | 
| 1447     if (transitioned_maps->at(i).is_null()) { | 1331     if (transitioned_maps->at(i).is_null()) { | 
| 1448       __ Jump(handler_stubs->at(i), RelocInfo::CODE_TARGET, eq, | 1332       __ Jump(handler_stubs->at(i), RelocInfo::CODE_TARGET, eq, | 
| 1449           scratch1(), Operand(receiver_maps->at(i))); | 1333           scratch1(), Operand(receiver_maps->at(i))); | 
| 1450     } else { | 1334     } else { | 
| 1451       Label next_map; | 1335       Label next_map; | 
| 1452       __ Branch(&next_map, ne, scratch1(), Operand(receiver_maps->at(i))); | 1336       __ Branch(&next_map, ne, scratch1(), Operand(receiver_maps->at(i))); | 
| 1453       __ li(transition_map(), Operand(transitioned_maps->at(i))); | 1337       __ li(transition_map(), Operand(transitioned_maps->at(i))); | 
| 1454       __ Jump(handler_stubs->at(i), RelocInfo::CODE_TARGET); | 1338       __ Jump(handler_stubs->at(i), RelocInfo::CODE_TARGET); | 
| 1455       __ bind(&next_map); | 1339       __ bind(&next_map); | 
| 1456     } | 1340     } | 
| 1457   } | 1341   } | 
| 1458 | 1342 | 
| 1459   __ bind(&miss); | 1343   __ bind(&miss); | 
| 1460   TailCallBuiltin(masm(), MissBuiltin(kind())); | 1344   TailCallBuiltin(masm(), MissBuiltin(kind())); | 
| 1461 | 1345 | 
| 1462   // Return the generated code. | 1346   // Return the generated code. | 
| 1463   return GetICCode( | 1347   return GetCode(kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC); | 
| 1464       kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC); |  | 
| 1465 } | 1348 } | 
| 1466 | 1349 | 
| 1467 | 1350 | 
| 1468 #undef __ | 1351 #undef __ | 
| 1469 #define __ ACCESS_MASM(masm) | 1352 #define __ ACCESS_MASM(masm) | 
| 1470 | 1353 | 
| 1471 | 1354 | 
| 1472 void KeyedLoadStubCompiler::GenerateLoadDictionaryElement( | 1355 void IndexedHandlerCompiler::GenerateLoadDictionaryElement( | 
| 1473     MacroAssembler* masm) { | 1356     MacroAssembler* masm) { | 
| 1474   // The return address is in ra | 1357   // The return address is in ra | 
| 1475   Label slow, miss; | 1358   Label slow, miss; | 
| 1476 | 1359 | 
| 1477   Register key = LoadIC::NameRegister(); | 1360   Register key = LoadIC::NameRegister(); | 
| 1478   Register receiver = LoadIC::ReceiverRegister(); | 1361   Register receiver = LoadIC::ReceiverRegister(); | 
| 1479   ASSERT(receiver.is(a1)); | 1362   ASSERT(receiver.is(a1)); | 
| 1480   ASSERT(key.is(a2)); | 1363   ASSERT(key.is(a2)); | 
| 1481 | 1364 | 
| 1482   __ UntagAndJumpIfNotSmi(a6, key, &miss); | 1365   __ UntagAndJumpIfNotSmi(a6, key, &miss); | 
| (...skipping 15 matching lines...) Expand all  Loading... | 
| 1498 | 1381 | 
| 1499   TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); | 1382   TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); | 
| 1500 } | 1383 } | 
| 1501 | 1384 | 
| 1502 | 1385 | 
| 1503 #undef __ | 1386 #undef __ | 
| 1504 | 1387 | 
| 1505 } }  // namespace v8::internal | 1388 } }  // namespace v8::internal | 
| 1506 | 1389 | 
| 1507 #endif  // V8_TARGET_ARCH_MIPS64 | 1390 #endif  // V8_TARGET_ARCH_MIPS64 | 
| OLD | NEW | 
|---|