| 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_X64 | 7 #if V8_TARGET_ARCH_X64 | 
| 8 | 8 | 
| 9 #include "src/arguments.h" | 9 #include "src/arguments.h" | 
| 10 #include "src/codegen.h" | 10 #include "src/codegen.h" | 
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 79 #endif | 79 #endif | 
| 80 | 80 | 
| 81   // Jump to the first instruction in the code stub. | 81   // Jump to the first instruction in the code stub. | 
| 82   __ addp(kScratchRegister, Immediate(Code::kHeaderSize - kHeapObjectTag)); | 82   __ addp(kScratchRegister, Immediate(Code::kHeaderSize - kHeapObjectTag)); | 
| 83   __ jmp(kScratchRegister); | 83   __ jmp(kScratchRegister); | 
| 84 | 84 | 
| 85   __ bind(&miss); | 85   __ bind(&miss); | 
| 86 } | 86 } | 
| 87 | 87 | 
| 88 | 88 | 
| 89 void StubCompiler::GenerateDictionaryNegativeLookup(MacroAssembler* masm, | 89 void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup( | 
| 90                                                     Label* miss_label, | 90     MacroAssembler* masm, Label* miss_label, Register receiver, | 
| 91                                                     Register receiver, | 91     Handle<Name> name, Register scratch0, Register scratch1) { | 
| 92                                                     Handle<Name> name, |  | 
| 93                                                     Register scratch0, |  | 
| 94                                                     Register scratch1) { |  | 
| 95   ASSERT(name->IsUniqueName()); | 92   ASSERT(name->IsUniqueName()); | 
| 96   ASSERT(!receiver.is(scratch0)); | 93   ASSERT(!receiver.is(scratch0)); | 
| 97   Counters* counters = masm->isolate()->counters(); | 94   Counters* counters = masm->isolate()->counters(); | 
| 98   __ IncrementCounter(counters->negative_lookups(), 1); | 95   __ IncrementCounter(counters->negative_lookups(), 1); | 
| 99   __ IncrementCounter(counters->negative_lookups_miss(), 1); | 96   __ IncrementCounter(counters->negative_lookups_miss(), 1); | 
| 100 | 97 | 
| 101   __ movp(scratch0, FieldOperand(receiver, HeapObject::kMapOffset)); | 98   __ movp(scratch0, FieldOperand(receiver, HeapObject::kMapOffset)); | 
| 102 | 99 | 
| 103   const int kInterceptorOrAccessCheckNeededMask = | 100   const int kInterceptorOrAccessCheckNeededMask = | 
| 104       (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded); | 101       (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded); | 
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 192   // Probe the secondary table. | 189   // Probe the secondary table. | 
| 193   ProbeTable(isolate, masm, flags, kSecondary, receiver, name, scratch); | 190   ProbeTable(isolate, masm, flags, kSecondary, receiver, name, scratch); | 
| 194 | 191 | 
| 195   // Cache miss: Fall-through and let caller handle the miss by | 192   // Cache miss: Fall-through and let caller handle the miss by | 
| 196   // entering the runtime system. | 193   // entering the runtime system. | 
| 197   __ bind(&miss); | 194   __ bind(&miss); | 
| 198   __ IncrementCounter(counters->megamorphic_stub_cache_misses(), 1); | 195   __ IncrementCounter(counters->megamorphic_stub_cache_misses(), 1); | 
| 199 } | 196 } | 
| 200 | 197 | 
| 201 | 198 | 
| 202 void StubCompiler::GenerateLoadGlobalFunctionPrototype(MacroAssembler* masm, | 199 void NamedLoadHandlerCompiler::GenerateDirectLoadGlobalFunctionPrototype( | 
| 203                                                        int index, | 200     MacroAssembler* masm, int index, Register prototype, Label* miss) { | 
| 204                                                        Register prototype) { |  | 
| 205   // Load the global or builtins object from the current context. |  | 
| 206   __ movp(prototype, |  | 
| 207           Operand(rsi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); |  | 
| 208   // Load the native context from the global or builtins object. |  | 
| 209   __ movp(prototype, |  | 
| 210           FieldOperand(prototype, GlobalObject::kNativeContextOffset)); |  | 
| 211   // Load the function from the native context. |  | 
| 212   __ movp(prototype, Operand(prototype, Context::SlotOffset(index))); |  | 
| 213   // Load the initial map.  The global functions all have initial maps. |  | 
| 214   __ movp(prototype, |  | 
| 215           FieldOperand(prototype, JSFunction::kPrototypeOrInitialMapOffset)); |  | 
| 216   // Load the prototype from the initial map. |  | 
| 217   __ movp(prototype, FieldOperand(prototype, Map::kPrototypeOffset)); |  | 
| 218 } |  | 
| 219 |  | 
| 220 |  | 
| 221 void StubCompiler::GenerateDirectLoadGlobalFunctionPrototype( |  | 
| 222     MacroAssembler* masm, |  | 
| 223     int index, |  | 
| 224     Register prototype, |  | 
| 225     Label* miss) { |  | 
| 226   Isolate* isolate = masm->isolate(); | 201   Isolate* isolate = masm->isolate(); | 
| 227   // Get the global function with the given index. | 202   // Get the global function with the given index. | 
| 228   Handle<JSFunction> function( | 203   Handle<JSFunction> function( | 
| 229       JSFunction::cast(isolate->native_context()->get(index))); | 204       JSFunction::cast(isolate->native_context()->get(index))); | 
| 230 | 205 | 
| 231   // Check we're still in the same context. | 206   // Check we're still in the same context. | 
| 232   Register scratch = prototype; | 207   Register scratch = prototype; | 
| 233   const int offset = Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX); | 208   const int offset = Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX); | 
| 234   __ movp(scratch, Operand(rsi, offset)); | 209   __ movp(scratch, Operand(rsi, offset)); | 
| 235   __ movp(scratch, FieldOperand(scratch, GlobalObject::kNativeContextOffset)); | 210   __ movp(scratch, FieldOperand(scratch, GlobalObject::kNativeContextOffset)); | 
| 236   __ Cmp(Operand(scratch, Context::SlotOffset(index)), function); | 211   __ Cmp(Operand(scratch, Context::SlotOffset(index)), function); | 
| 237   __ j(not_equal, miss); | 212   __ j(not_equal, miss); | 
| 238 | 213 | 
| 239   // Load its initial map. The global functions all have initial maps. | 214   // Load its initial map. The global functions all have initial maps. | 
| 240   __ Move(prototype, Handle<Map>(function->initial_map())); | 215   __ Move(prototype, Handle<Map>(function->initial_map())); | 
| 241   // Load the prototype from the initial map. | 216   // Load the prototype from the initial map. | 
| 242   __ movp(prototype, FieldOperand(prototype, Map::kPrototypeOffset)); | 217   __ movp(prototype, FieldOperand(prototype, Map::kPrototypeOffset)); | 
| 243 } | 218 } | 
| 244 | 219 | 
| 245 | 220 | 
| 246 void StubCompiler::GenerateLoadArrayLength(MacroAssembler* masm, | 221 void NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype( | 
| 247                                            Register receiver, | 222     MacroAssembler* masm, Register receiver, Register result, Register scratch, | 
| 248                                            Register scratch, | 223     Label* miss_label) { | 
| 249                                            Label* miss_label) { |  | 
| 250   // Check that the receiver isn't a smi. |  | 
| 251   __ JumpIfSmi(receiver, miss_label); |  | 
| 252 |  | 
| 253   // Check that the object is a JS array. |  | 
| 254   __ CmpObjectType(receiver, JS_ARRAY_TYPE, scratch); |  | 
| 255   __ j(not_equal, miss_label); |  | 
| 256 |  | 
| 257   // Load length directly from the JS array. |  | 
| 258   __ movp(rax, FieldOperand(receiver, JSArray::kLengthOffset)); |  | 
| 259   __ ret(0); |  | 
| 260 } |  | 
| 261 |  | 
| 262 |  | 
| 263 void StubCompiler::GenerateLoadFunctionPrototype(MacroAssembler* masm, |  | 
| 264                                                  Register receiver, |  | 
| 265                                                  Register result, |  | 
| 266                                                  Register scratch, |  | 
| 267                                                  Label* miss_label) { |  | 
| 268   __ TryGetFunctionPrototype(receiver, result, miss_label); | 224   __ TryGetFunctionPrototype(receiver, result, miss_label); | 
| 269   if (!result.is(rax)) __ movp(rax, result); | 225   if (!result.is(rax)) __ movp(rax, result); | 
| 270   __ ret(0); | 226   __ ret(0); | 
| 271 } | 227 } | 
| 272 | 228 | 
| 273 | 229 | 
| 274 void StubCompiler::GenerateFastPropertyLoad(MacroAssembler* masm, |  | 
| 275                                             Register dst, |  | 
| 276                                             Register src, |  | 
| 277                                             bool inobject, |  | 
| 278                                             int index, |  | 
| 279                                             Representation representation) { |  | 
| 280   ASSERT(!representation.IsDouble()); |  | 
| 281   int offset = index * kPointerSize; |  | 
| 282   if (!inobject) { |  | 
| 283     // Calculate the offset into the properties array. |  | 
| 284     offset = offset + FixedArray::kHeaderSize; |  | 
| 285     __ movp(dst, FieldOperand(src, JSObject::kPropertiesOffset)); |  | 
| 286     src = dst; |  | 
| 287   } |  | 
| 288   __ movp(dst, FieldOperand(src, offset)); |  | 
| 289 } |  | 
| 290 |  | 
| 291 |  | 
| 292 static void PushInterceptorArguments(MacroAssembler* masm, | 230 static void PushInterceptorArguments(MacroAssembler* masm, | 
| 293                                      Register receiver, | 231                                      Register receiver, | 
| 294                                      Register holder, | 232                                      Register holder, | 
| 295                                      Register name, | 233                                      Register name, | 
| 296                                      Handle<JSObject> holder_obj) { | 234                                      Handle<JSObject> holder_obj) { | 
| 297   STATIC_ASSERT(StubCache::kInterceptorArgsNameIndex == 0); | 235   STATIC_ASSERT(StubCache::kInterceptorArgsNameIndex == 0); | 
| 298   STATIC_ASSERT(StubCache::kInterceptorArgsInfoIndex == 1); | 236   STATIC_ASSERT(StubCache::kInterceptorArgsInfoIndex == 1); | 
| 299   STATIC_ASSERT(StubCache::kInterceptorArgsThisIndex == 2); | 237   STATIC_ASSERT(StubCache::kInterceptorArgsThisIndex == 2); | 
| 300   STATIC_ASSERT(StubCache::kInterceptorArgsHolderIndex == 3); | 238   STATIC_ASSERT(StubCache::kInterceptorArgsHolderIndex == 3); | 
| 301   STATIC_ASSERT(StubCache::kInterceptorArgsLength == 4); | 239   STATIC_ASSERT(StubCache::kInterceptorArgsLength == 4); | 
| (...skipping 15 matching lines...) Expand all  Loading... | 
| 317     Handle<JSObject> holder_obj, | 255     Handle<JSObject> holder_obj, | 
| 318     IC::UtilityId id) { | 256     IC::UtilityId id) { | 
| 319   PushInterceptorArguments(masm, receiver, holder, name, holder_obj); | 257   PushInterceptorArguments(masm, receiver, holder, name, holder_obj); | 
| 320   __ CallExternalReference( | 258   __ CallExternalReference( | 
| 321       ExternalReference(IC_Utility(id), masm->isolate()), | 259       ExternalReference(IC_Utility(id), masm->isolate()), | 
| 322       StubCache::kInterceptorArgsLength); | 260       StubCache::kInterceptorArgsLength); | 
| 323 } | 261 } | 
| 324 | 262 | 
| 325 | 263 | 
| 326 // Generate call to api function. | 264 // Generate call to api function. | 
| 327 void StubCompiler::GenerateFastApiCall(MacroAssembler* masm, | 265 void PropertyHandlerCompiler::GenerateFastApiCall( | 
| 328                                        const CallOptimization& optimization, | 266     MacroAssembler* masm, const CallOptimization& optimization, | 
| 329                                        Handle<Map> receiver_map, | 267     Handle<Map> receiver_map, Register receiver, Register scratch_in, | 
| 330                                        Register receiver, | 268     bool is_store, int argc, Register* values) { | 
| 331                                        Register scratch_in, |  | 
| 332                                        bool is_store, |  | 
| 333                                        int argc, |  | 
| 334                                        Register* values) { |  | 
| 335   ASSERT(optimization.is_simple_api_call()); | 269   ASSERT(optimization.is_simple_api_call()); | 
| 336 | 270 | 
| 337   __ PopReturnAddressTo(scratch_in); | 271   __ PopReturnAddressTo(scratch_in); | 
| 338   // receiver | 272   // receiver | 
| 339   __ Push(receiver); | 273   __ Push(receiver); | 
| 340   // Write the arguments to stack frame. | 274   // Write the arguments to stack frame. | 
| 341   for (int i = 0; i < argc; i++) { | 275   for (int i = 0; i < argc; i++) { | 
| 342     Register arg = values[argc-1-i]; | 276     Register arg = values[argc-1-i]; | 
| 343     ASSERT(!receiver.is(arg)); | 277     ASSERT(!receiver.is(arg)); | 
| 344     ASSERT(!scratch_in.is(arg)); | 278     ASSERT(!scratch_in.is(arg)); | 
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 395   Address function_address = v8::ToCData<Address>(api_call_info->callback()); | 329   Address function_address = v8::ToCData<Address>(api_call_info->callback()); | 
| 396   __ Move( | 330   __ Move( | 
| 397       api_function_address, function_address, RelocInfo::EXTERNAL_REFERENCE); | 331       api_function_address, function_address, RelocInfo::EXTERNAL_REFERENCE); | 
| 398 | 332 | 
| 399   // Jump to stub. | 333   // Jump to stub. | 
| 400   CallApiFunctionStub stub(isolate, is_store, call_data_undefined, argc); | 334   CallApiFunctionStub stub(isolate, is_store, call_data_undefined, argc); | 
| 401   __ TailCallStub(&stub); | 335   __ TailCallStub(&stub); | 
| 402 } | 336 } | 
| 403 | 337 | 
| 404 | 338 | 
| 405 void StoreStubCompiler::GenerateRestoreName(MacroAssembler* masm, | 339 void NamedStoreHandlerCompiler::GenerateRestoreName(MacroAssembler* masm, | 
| 406                                             Label* label, | 340                                                     Label* label, | 
| 407                                             Handle<Name> name) { | 341                                                     Handle<Name> name) { | 
| 408   if (!label->is_unused()) { | 342   if (!label->is_unused()) { | 
| 409     __ bind(label); | 343     __ bind(label); | 
| 410     __ Move(this->name(), name); | 344     __ Move(this->name(), name); | 
| 411   } | 345   } | 
| 412 } | 346 } | 
| 413 | 347 | 
| 414 | 348 | 
| 415 void StubCompiler::GenerateCheckPropertyCell(MacroAssembler* masm, | 349 void PropertyHandlerCompiler::GenerateCheckPropertyCell( | 
| 416                                              Handle<JSGlobalObject> global, | 350     MacroAssembler* masm, Handle<JSGlobalObject> global, Handle<Name> name, | 
| 417                                              Handle<Name> name, | 351     Register scratch, Label* miss) { | 
| 418                                              Register scratch, |  | 
| 419                                              Label* miss) { |  | 
| 420   Handle<PropertyCell> cell = | 352   Handle<PropertyCell> cell = | 
| 421       JSGlobalObject::EnsurePropertyCell(global, name); | 353       JSGlobalObject::EnsurePropertyCell(global, name); | 
| 422   ASSERT(cell->value()->IsTheHole()); | 354   ASSERT(cell->value()->IsTheHole()); | 
| 423   __ Move(scratch, cell); | 355   __ Move(scratch, cell); | 
| 424   __ Cmp(FieldOperand(scratch, Cell::kValueOffset), | 356   __ Cmp(FieldOperand(scratch, Cell::kValueOffset), | 
| 425          masm->isolate()->factory()->the_hole_value()); | 357          masm->isolate()->factory()->the_hole_value()); | 
| 426   __ j(not_equal, miss); | 358   __ j(not_equal, miss); | 
| 427 } | 359 } | 
| 428 | 360 | 
| 429 | 361 | 
| 430 void StoreStubCompiler::GenerateNegativeHolderLookup( | 362 void NamedStoreHandlerCompiler::GenerateNegativeHolderLookup( | 
| 431     MacroAssembler* masm, | 363     MacroAssembler* masm, Handle<JSObject> holder, Register holder_reg, | 
| 432     Handle<JSObject> holder, | 364     Handle<Name> name, Label* miss) { | 
| 433     Register holder_reg, |  | 
| 434     Handle<Name> name, |  | 
| 435     Label* miss) { |  | 
| 436   if (holder->IsJSGlobalObject()) { | 365   if (holder->IsJSGlobalObject()) { | 
| 437     GenerateCheckPropertyCell( | 366     GenerateCheckPropertyCell( | 
| 438         masm, Handle<JSGlobalObject>::cast(holder), name, scratch1(), miss); | 367         masm, Handle<JSGlobalObject>::cast(holder), name, scratch1(), miss); | 
| 439   } else if (!holder->HasFastProperties() && !holder->IsJSGlobalProxy()) { | 368   } else if (!holder->HasFastProperties() && !holder->IsJSGlobalProxy()) { | 
| 440     GenerateDictionaryNegativeLookup( | 369     GenerateDictionaryNegativeLookup( | 
| 441         masm, miss, holder_reg, name, scratch1(), scratch2()); | 370         masm, miss, holder_reg, name, scratch1(), scratch2()); | 
| 442   } | 371   } | 
| 443 } | 372 } | 
| 444 | 373 | 
| 445 | 374 | 
| 446 // Receiver_reg is preserved on jumps to miss_label, but may be destroyed if | 375 // Receiver_reg is preserved on jumps to miss_label, but may be destroyed if | 
| 447 // store is successful. | 376 // store is successful. | 
| 448 void StoreStubCompiler::GenerateStoreTransition(MacroAssembler* masm, | 377 void NamedStoreHandlerCompiler::GenerateStoreTransition( | 
| 449                                                 Handle<JSObject> object, | 378     MacroAssembler* masm, Handle<JSObject> object, LookupResult* lookup, | 
| 450                                                 LookupResult* lookup, | 379     Handle<Map> transition, Handle<Name> name, Register receiver_reg, | 
| 451                                                 Handle<Map> transition, | 380     Register storage_reg, Register value_reg, Register scratch1, | 
| 452                                                 Handle<Name> name, | 381     Register scratch2, Register unused, Label* miss_label, Label* slow) { | 
| 453                                                 Register receiver_reg, |  | 
| 454                                                 Register storage_reg, |  | 
| 455                                                 Register value_reg, |  | 
| 456                                                 Register scratch1, |  | 
| 457                                                 Register scratch2, |  | 
| 458                                                 Register unused, |  | 
| 459                                                 Label* miss_label, |  | 
| 460                                                 Label* slow) { |  | 
| 461   int descriptor = transition->LastAdded(); | 382   int descriptor = transition->LastAdded(); | 
| 462   DescriptorArray* descriptors = transition->instance_descriptors(); | 383   DescriptorArray* descriptors = transition->instance_descriptors(); | 
| 463   PropertyDetails details = descriptors->GetDetails(descriptor); | 384   PropertyDetails details = descriptors->GetDetails(descriptor); | 
| 464   Representation representation = details.representation(); | 385   Representation representation = details.representation(); | 
| 465   ASSERT(!representation.IsNone()); | 386   ASSERT(!representation.IsNone()); | 
| 466 | 387 | 
| 467   if (details.type() == CONSTANT) { | 388   if (details.type() == CONSTANT) { | 
| 468     Handle<Object> constant(descriptors->GetValue(descriptor), masm->isolate()); | 389     Handle<Object> constant(descriptors->GetValue(descriptor), masm->isolate()); | 
| 469     __ Cmp(value_reg, constant); | 390     __ Cmp(value_reg, constant); | 
| 470     __ j(not_equal, miss_label); | 391     __ j(not_equal, miss_label); | 
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 598   } | 519   } | 
| 599 | 520 | 
| 600   // Return the value (register rax). | 521   // Return the value (register rax). | 
| 601   ASSERT(value_reg.is(rax)); | 522   ASSERT(value_reg.is(rax)); | 
| 602   __ ret(0); | 523   __ ret(0); | 
| 603 } | 524 } | 
| 604 | 525 | 
| 605 | 526 | 
| 606 // Both name_reg and receiver_reg are preserved on jumps to miss_label, | 527 // Both name_reg and receiver_reg are preserved on jumps to miss_label, | 
| 607 // but may be destroyed if store is successful. | 528 // but may be destroyed if store is successful. | 
| 608 void StoreStubCompiler::GenerateStoreField(MacroAssembler* masm, | 529 void NamedStoreHandlerCompiler::GenerateStoreField( | 
| 609                                            Handle<JSObject> object, | 530     MacroAssembler* masm, Handle<JSObject> object, LookupResult* lookup, | 
| 610                                            LookupResult* lookup, | 531     Register receiver_reg, Register name_reg, Register value_reg, | 
| 611                                            Register receiver_reg, | 532     Register scratch1, Register scratch2, Label* miss_label) { | 
| 612                                            Register name_reg, |  | 
| 613                                            Register value_reg, |  | 
| 614                                            Register scratch1, |  | 
| 615                                            Register scratch2, |  | 
| 616                                            Label* miss_label) { |  | 
| 617   // Stub never generated for non-global objects that require access | 533   // Stub never generated for non-global objects that require access | 
| 618   // checks. | 534   // checks. | 
| 619   ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); | 535   ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); | 
| 620 | 536 | 
| 621   FieldIndex index = lookup->GetFieldIndex(); | 537   FieldIndex index = lookup->GetFieldIndex(); | 
| 622 | 538 | 
| 623   Representation representation = lookup->representation(); | 539   Representation representation = lookup->representation(); | 
| 624   ASSERT(!representation.IsNone()); | 540   ASSERT(!representation.IsNone()); | 
| 625   if (representation.IsSmi()) { | 541   if (representation.IsSmi()) { | 
| 626     __ JumpIfNotSmi(value_reg, miss_label); | 542     __ JumpIfNotSmi(value_reg, miss_label); | 
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 700           EMIT_REMEMBERED_SET, smi_check); | 616           EMIT_REMEMBERED_SET, smi_check); | 
| 701     } | 617     } | 
| 702   } | 618   } | 
| 703 | 619 | 
| 704   // Return the value (register rax). | 620   // Return the value (register rax). | 
| 705   ASSERT(value_reg.is(rax)); | 621   ASSERT(value_reg.is(rax)); | 
| 706   __ ret(0); | 622   __ ret(0); | 
| 707 } | 623 } | 
| 708 | 624 | 
| 709 | 625 | 
| 710 void StubCompiler::GenerateTailCall(MacroAssembler* masm, Handle<Code> code) { | 626 void PropertyAccessCompiler::GenerateTailCall(MacroAssembler* masm, | 
|  | 627                                               Handle<Code> code) { | 
| 711   __ jmp(code, RelocInfo::CODE_TARGET); | 628   __ jmp(code, RelocInfo::CODE_TARGET); | 
| 712 } | 629 } | 
| 713 | 630 | 
| 714 | 631 | 
| 715 #undef __ | 632 #undef __ | 
| 716 #define __ ACCESS_MASM((masm())) | 633 #define __ ACCESS_MASM((masm())) | 
| 717 | 634 | 
| 718 | 635 | 
| 719 Register StubCompiler::CheckPrototypes(Handle<HeapType> type, | 636 Register PropertyHandlerCompiler::CheckPrototypes( | 
| 720                                        Register object_reg, | 637     Handle<HeapType> type, Register object_reg, Handle<JSObject> holder, | 
| 721                                        Handle<JSObject> holder, | 638     Register holder_reg, Register scratch1, Register scratch2, | 
| 722                                        Register holder_reg, | 639     Handle<Name> name, Label* miss, PrototypeCheckType check) { | 
| 723                                        Register scratch1, |  | 
| 724                                        Register scratch2, |  | 
| 725                                        Handle<Name> name, |  | 
| 726                                        Label* miss, |  | 
| 727                                        PrototypeCheckType check) { |  | 
| 728   Handle<Map> receiver_map(IC::TypeToMap(*type, isolate())); | 640   Handle<Map> receiver_map(IC::TypeToMap(*type, isolate())); | 
| 729 | 641 | 
| 730   // Make sure there's no overlap between holder and object registers. | 642   // Make sure there's no overlap between holder and object registers. | 
| 731   ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); | 643   ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); | 
| 732   ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) | 644   ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) | 
| 733          && !scratch2.is(scratch1)); | 645          && !scratch2.is(scratch1)); | 
| 734 | 646 | 
| 735   // Keep track of the current object in register reg.  On the first | 647   // Keep track of the current object in register reg.  On the first | 
| 736   // iteration, reg is an alias for object_reg, on later iterations, | 648   // iteration, reg is an alias for object_reg, on later iterations, | 
| 737   // it is an alias for holder_reg. | 649   // it is an alias for holder_reg. | 
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 825          !current_map->is_access_check_needed()); | 737          !current_map->is_access_check_needed()); | 
| 826   if (current_map->IsJSGlobalProxyMap()) { | 738   if (current_map->IsJSGlobalProxyMap()) { | 
| 827     __ CheckAccessGlobalProxy(reg, scratch1, miss); | 739     __ CheckAccessGlobalProxy(reg, scratch1, miss); | 
| 828   } | 740   } | 
| 829 | 741 | 
| 830   // Return the register containing the holder. | 742   // Return the register containing the holder. | 
| 831   return reg; | 743   return reg; | 
| 832 } | 744 } | 
| 833 | 745 | 
| 834 | 746 | 
| 835 void LoadStubCompiler::HandlerFrontendFooter(Handle<Name> name, Label* miss) { | 747 void NamedLoadHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) { | 
| 836   if (!miss->is_unused()) { | 748   if (!miss->is_unused()) { | 
| 837     Label success; | 749     Label success; | 
| 838     __ jmp(&success); | 750     __ jmp(&success); | 
| 839     __ bind(miss); | 751     __ bind(miss); | 
| 840     TailCallBuiltin(masm(), MissBuiltin(kind())); | 752     TailCallBuiltin(masm(), MissBuiltin(kind())); | 
| 841     __ bind(&success); | 753     __ bind(&success); | 
| 842   } | 754   } | 
| 843 } | 755 } | 
| 844 | 756 | 
| 845 | 757 | 
| 846 void StoreStubCompiler::HandlerFrontendFooter(Handle<Name> name, Label* miss) { | 758 void NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) { | 
| 847   if (!miss->is_unused()) { | 759   if (!miss->is_unused()) { | 
| 848     Label success; | 760     Label success; | 
| 849     __ jmp(&success); | 761     __ jmp(&success); | 
| 850     GenerateRestoreName(masm(), miss, name); | 762     GenerateRestoreName(masm(), miss, name); | 
| 851     TailCallBuiltin(masm(), MissBuiltin(kind())); | 763     TailCallBuiltin(masm(), MissBuiltin(kind())); | 
| 852     __ bind(&success); | 764     __ bind(&success); | 
| 853   } | 765   } | 
| 854 } | 766 } | 
| 855 | 767 | 
| 856 | 768 | 
| 857 Register LoadStubCompiler::CallbackHandlerFrontend( | 769 Register NamedLoadHandlerCompiler::CallbackFrontend(Handle<HeapType> type, | 
| 858     Handle<HeapType> type, | 770                                                     Register object_reg, | 
| 859     Register object_reg, | 771                                                     Handle<JSObject> holder, | 
| 860     Handle<JSObject> holder, | 772                                                     Handle<Name> name, | 
| 861     Handle<Name> name, | 773                                                     Handle<Object> callback) { | 
| 862     Handle<Object> callback) { |  | 
| 863   Label miss; | 774   Label miss; | 
| 864 | 775 | 
| 865   Register reg = HandlerFrontendHeader(type, object_reg, holder, name, &miss); | 776   Register reg = FrontendHeader(type, object_reg, holder, name, &miss); | 
| 866 | 777 | 
| 867   if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) { | 778   if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) { | 
| 868     ASSERT(!reg.is(scratch2())); | 779     ASSERT(!reg.is(scratch2())); | 
| 869     ASSERT(!reg.is(scratch3())); | 780     ASSERT(!reg.is(scratch3())); | 
| 870     ASSERT(!reg.is(scratch4())); | 781     ASSERT(!reg.is(scratch4())); | 
| 871 | 782 | 
| 872     // Load the properties dictionary. | 783     // Load the properties dictionary. | 
| 873     Register dictionary = scratch4(); | 784     Register dictionary = scratch4(); | 
| 874     __ movp(dictionary, FieldOperand(reg, JSObject::kPropertiesOffset)); | 785     __ movp(dictionary, FieldOperand(reg, JSObject::kPropertiesOffset)); | 
| 875 | 786 | 
| (...skipping 16 matching lines...) Expand all  Loading... | 
| 892         NameDictionary::kElementsStartIndex * kPointerSize; | 803         NameDictionary::kElementsStartIndex * kPointerSize; | 
| 893     const int kValueOffset = kElementsStartOffset + kPointerSize; | 804     const int kValueOffset = kElementsStartOffset + kPointerSize; | 
| 894     __ movp(scratch2(), | 805     __ movp(scratch2(), | 
| 895             Operand(dictionary, index, times_pointer_size, | 806             Operand(dictionary, index, times_pointer_size, | 
| 896                     kValueOffset - kHeapObjectTag)); | 807                     kValueOffset - kHeapObjectTag)); | 
| 897     __ Move(scratch3(), callback, RelocInfo::EMBEDDED_OBJECT); | 808     __ Move(scratch3(), callback, RelocInfo::EMBEDDED_OBJECT); | 
| 898     __ cmpp(scratch2(), scratch3()); | 809     __ cmpp(scratch2(), scratch3()); | 
| 899     __ j(not_equal, &miss); | 810     __ j(not_equal, &miss); | 
| 900   } | 811   } | 
| 901 | 812 | 
| 902   HandlerFrontendFooter(name, &miss); | 813   FrontendFooter(name, &miss); | 
| 903   return reg; | 814   return reg; | 
| 904 } | 815 } | 
| 905 | 816 | 
| 906 | 817 | 
| 907 void LoadStubCompiler::GenerateLoadField(Register reg, | 818 void NamedLoadHandlerCompiler::GenerateLoadField( | 
| 908                                          Handle<JSObject> holder, | 819     Register reg, Handle<JSObject> holder, FieldIndex field, | 
| 909                                          FieldIndex field, | 820     Representation representation) { | 
| 910                                          Representation representation) { |  | 
| 911   if (!reg.is(receiver())) __ movp(receiver(), reg); | 821   if (!reg.is(receiver())) __ movp(receiver(), reg); | 
| 912   LoadFieldStub stub(isolate(), field); | 822   LoadFieldStub stub(isolate(), field); | 
| 913   GenerateTailCall(masm(), stub.GetCode()); | 823   GenerateTailCall(masm(), stub.GetCode()); | 
| 914 } | 824 } | 
| 915 | 825 | 
| 916 | 826 | 
| 917 void LoadStubCompiler::GenerateLoadCallback( | 827 void NamedLoadHandlerCompiler::GenerateLoadCallback( | 
| 918     Register reg, | 828     Register reg, Handle<ExecutableAccessorInfo> callback) { | 
| 919     Handle<ExecutableAccessorInfo> callback) { |  | 
| 920   // Insert additional parameters into the stack frame above return address. | 829   // Insert additional parameters into the stack frame above return address. | 
| 921   ASSERT(!scratch4().is(reg)); | 830   ASSERT(!scratch4().is(reg)); | 
| 922   __ PopReturnAddressTo(scratch4()); | 831   __ PopReturnAddressTo(scratch4()); | 
| 923 | 832 | 
| 924   STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == 0); | 833   STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == 0); | 
| 925   STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 1); | 834   STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 1); | 
| 926   STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == 2); | 835   STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == 2); | 
| 927   STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 3); | 836   STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 3); | 
| 928   STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == 4); | 837   STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == 4); | 
| 929   STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 5); | 838   STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 5); | 
| (...skipping 22 matching lines...) Expand all  Loading... | 
| 952   // Abi for CallApiGetter | 861   // Abi for CallApiGetter | 
| 953   Register api_function_address = r8; | 862   Register api_function_address = r8; | 
| 954   Address getter_address = v8::ToCData<Address>(callback->getter()); | 863   Address getter_address = v8::ToCData<Address>(callback->getter()); | 
| 955   __ Move(api_function_address, getter_address, RelocInfo::EXTERNAL_REFERENCE); | 864   __ Move(api_function_address, getter_address, RelocInfo::EXTERNAL_REFERENCE); | 
| 956 | 865 | 
| 957   CallApiGetterStub stub(isolate()); | 866   CallApiGetterStub stub(isolate()); | 
| 958   __ TailCallStub(&stub); | 867   __ TailCallStub(&stub); | 
| 959 } | 868 } | 
| 960 | 869 | 
| 961 | 870 | 
| 962 void LoadStubCompiler::GenerateLoadConstant(Handle<Object> value) { | 871 void NamedLoadHandlerCompiler::GenerateLoadConstant(Handle<Object> value) { | 
| 963   // Return the constant value. | 872   // Return the constant value. | 
| 964   __ Move(rax, value); | 873   __ Move(rax, value); | 
| 965   __ ret(0); | 874   __ ret(0); | 
| 966 } | 875 } | 
| 967 | 876 | 
| 968 | 877 | 
| 969 void LoadStubCompiler::GenerateLoadInterceptor( | 878 void NamedLoadHandlerCompiler::GenerateLoadInterceptor( | 
| 970     Register holder_reg, | 879     Register holder_reg, Handle<Object> object, | 
| 971     Handle<Object> object, | 880     Handle<JSObject> interceptor_holder, LookupResult* lookup, | 
| 972     Handle<JSObject> interceptor_holder, |  | 
| 973     LookupResult* lookup, |  | 
| 974     Handle<Name> name) { | 881     Handle<Name> name) { | 
| 975   ASSERT(interceptor_holder->HasNamedInterceptor()); | 882   ASSERT(interceptor_holder->HasNamedInterceptor()); | 
| 976   ASSERT(!interceptor_holder->GetNamedInterceptor()->getter()->IsUndefined()); | 883   ASSERT(!interceptor_holder->GetNamedInterceptor()->getter()->IsUndefined()); | 
| 977 | 884 | 
| 978   // So far the most popular follow ups for interceptor loads are FIELD | 885   // So far the most popular follow ups for interceptor loads are FIELD | 
| 979   // and CALLBACKS, so inline only them, other cases may be added | 886   // and CALLBACKS, so inline only them, other cases may be added | 
| 980   // later. | 887   // later. | 
| 981   bool compile_followup_inline = false; | 888   bool compile_followup_inline = false; | 
| 982   if (lookup->IsFound() && lookup->IsCacheable()) { | 889   if (lookup->IsFound() && lookup->IsCacheable()) { | 
| 983     if (lookup->IsField()) { | 890     if (lookup->IsField()) { | 
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1050                              this->name(), interceptor_holder); | 957                              this->name(), interceptor_holder); | 
| 1051     __ PushReturnAddressFrom(scratch2()); | 958     __ PushReturnAddressFrom(scratch2()); | 
| 1052 | 959 | 
| 1053     ExternalReference ref = ExternalReference( | 960     ExternalReference ref = ExternalReference( | 
| 1054         IC_Utility(IC::kLoadPropertyWithInterceptor), isolate()); | 961         IC_Utility(IC::kLoadPropertyWithInterceptor), isolate()); | 
| 1055     __ TailCallExternalReference(ref, StubCache::kInterceptorArgsLength, 1); | 962     __ TailCallExternalReference(ref, StubCache::kInterceptorArgsLength, 1); | 
| 1056   } | 963   } | 
| 1057 } | 964 } | 
| 1058 | 965 | 
| 1059 | 966 | 
| 1060 Handle<Code> StoreStubCompiler::CompileStoreCallback( | 967 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback( | 
| 1061     Handle<JSObject> object, | 968     Handle<JSObject> object, Handle<JSObject> holder, Handle<Name> name, | 
| 1062     Handle<JSObject> holder, |  | 
| 1063     Handle<Name> name, |  | 
| 1064     Handle<ExecutableAccessorInfo> callback) { | 969     Handle<ExecutableAccessorInfo> callback) { | 
| 1065   Register holder_reg = HandlerFrontend( | 970   Register holder_reg = | 
| 1066       IC::CurrentTypeOf(object, isolate()), receiver(), holder, name); | 971       Frontend(IC::CurrentTypeOf(object, isolate()), receiver(), holder, name); | 
| 1067 | 972 | 
| 1068   __ PopReturnAddressTo(scratch1()); | 973   __ PopReturnAddressTo(scratch1()); | 
| 1069   __ Push(receiver()); | 974   __ Push(receiver()); | 
| 1070   __ Push(holder_reg); | 975   __ Push(holder_reg); | 
| 1071   __ Push(callback);  // callback info | 976   __ Push(callback);  // callback info | 
| 1072   __ Push(name); | 977   __ Push(name); | 
| 1073   __ Push(value()); | 978   __ Push(value()); | 
| 1074   __ PushReturnAddressFrom(scratch1()); | 979   __ PushReturnAddressFrom(scratch1()); | 
| 1075 | 980 | 
| 1076   // Do tail-call to the runtime system. | 981   // Do tail-call to the runtime system. | 
| 1077   ExternalReference store_callback_property = | 982   ExternalReference store_callback_property = | 
| 1078       ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate()); | 983       ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate()); | 
| 1079   __ TailCallExternalReference(store_callback_property, 5, 1); | 984   __ TailCallExternalReference(store_callback_property, 5, 1); | 
| 1080 | 985 | 
| 1081   // Return the generated code. | 986   // Return the generated code. | 
| 1082   return GetCode(kind(), Code::FAST, name); | 987   return GetCode(kind(), Code::FAST, name); | 
| 1083 } | 988 } | 
| 1084 | 989 | 
| 1085 | 990 | 
| 1086 #undef __ | 991 #undef __ | 
| 1087 #define __ ACCESS_MASM(masm) | 992 #define __ ACCESS_MASM(masm) | 
| 1088 | 993 | 
| 1089 | 994 | 
| 1090 void StoreStubCompiler::GenerateStoreViaSetter( | 995 void NamedStoreHandlerCompiler::GenerateStoreViaSetter( | 
| 1091     MacroAssembler* masm, | 996     MacroAssembler* masm, Handle<HeapType> type, Register receiver, | 
| 1092     Handle<HeapType> type, |  | 
| 1093     Register receiver, |  | 
| 1094     Handle<JSFunction> setter) { | 997     Handle<JSFunction> setter) { | 
| 1095   // ----------- S t a t e ------------- | 998   // ----------- S t a t e ------------- | 
| 1096   //  -- rsp[0] : return address | 999   //  -- rsp[0] : return address | 
| 1097   // ----------------------------------- | 1000   // ----------------------------------- | 
| 1098   { | 1001   { | 
| 1099     FrameScope scope(masm, StackFrame::INTERNAL); | 1002     FrameScope scope(masm, StackFrame::INTERNAL); | 
| 1100 | 1003 | 
| 1101     // Save value register, so we can restore it later. | 1004     // Save value register, so we can restore it later. | 
| 1102     __ Push(value()); | 1005     __ Push(value()); | 
| 1103 | 1006 | 
| (...skipping 23 matching lines...) Expand all  Loading... | 
| 1127     __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 1030     __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 
| 1128   } | 1031   } | 
| 1129   __ ret(0); | 1032   __ ret(0); | 
| 1130 } | 1033 } | 
| 1131 | 1034 | 
| 1132 | 1035 | 
| 1133 #undef __ | 1036 #undef __ | 
| 1134 #define __ ACCESS_MASM(masm()) | 1037 #define __ ACCESS_MASM(masm()) | 
| 1135 | 1038 | 
| 1136 | 1039 | 
| 1137 Handle<Code> StoreStubCompiler::CompileStoreInterceptor( | 1040 Handle<Code> NamedStoreHandlerCompiler::CompileStoreInterceptor( | 
| 1138     Handle<JSObject> object, | 1041     Handle<JSObject> object, Handle<Name> name) { | 
| 1139     Handle<Name> name) { |  | 
| 1140   __ PopReturnAddressTo(scratch1()); | 1042   __ PopReturnAddressTo(scratch1()); | 
| 1141   __ Push(receiver()); | 1043   __ Push(receiver()); | 
| 1142   __ Push(this->name()); | 1044   __ Push(this->name()); | 
| 1143   __ Push(value()); | 1045   __ Push(value()); | 
| 1144   __ PushReturnAddressFrom(scratch1()); | 1046   __ PushReturnAddressFrom(scratch1()); | 
| 1145 | 1047 | 
| 1146   // Do tail-call to the runtime system. | 1048   // Do tail-call to the runtime system. | 
| 1147   ExternalReference store_ic_property = | 1049   ExternalReference store_ic_property = | 
| 1148       ExternalReference(IC_Utility(IC::kStoreInterceptorProperty), isolate()); | 1050       ExternalReference(IC_Utility(IC::kStoreInterceptorProperty), isolate()); | 
| 1149   __ TailCallExternalReference(store_ic_property, 3, 1); | 1051   __ TailCallExternalReference(store_ic_property, 3, 1); | 
| 1150 | 1052 | 
| 1151   // Return the generated code. | 1053   // Return the generated code. | 
| 1152   return GetCode(kind(), Code::FAST, name); | 1054   return GetCode(kind(), Code::FAST, name); | 
| 1153 } | 1055 } | 
| 1154 | 1056 | 
| 1155 | 1057 | 
| 1156 void StoreStubCompiler::GenerateStoreArrayLength() { | 1058 void NamedStoreHandlerCompiler::GenerateStoreArrayLength() { | 
| 1157   // Prepare tail call to StoreIC_ArrayLength. | 1059   // Prepare tail call to StoreIC_ArrayLength. | 
| 1158   __ PopReturnAddressTo(scratch1()); | 1060   __ PopReturnAddressTo(scratch1()); | 
| 1159   __ Push(receiver()); | 1061   __ Push(receiver()); | 
| 1160   __ Push(value()); | 1062   __ Push(value()); | 
| 1161   __ PushReturnAddressFrom(scratch1()); | 1063   __ PushReturnAddressFrom(scratch1()); | 
| 1162 | 1064 | 
| 1163   ExternalReference ref = | 1065   ExternalReference ref = | 
| 1164       ExternalReference(IC_Utility(IC::kStoreIC_ArrayLength), | 1066       ExternalReference(IC_Utility(IC::kStoreIC_ArrayLength), | 
| 1165                         masm()->isolate()); | 1067                         masm()->isolate()); | 
| 1166   __ TailCallExternalReference(ref, 2, 1); | 1068   __ TailCallExternalReference(ref, 2, 1); | 
| 1167 } | 1069 } | 
| 1168 | 1070 | 
| 1169 | 1071 | 
| 1170 Handle<Code> KeyedStoreStubCompiler::CompileStorePolymorphic( | 1072 Handle<Code> PropertyICCompiler::CompileIndexedStorePolymorphic( | 
| 1171     MapHandleList* receiver_maps, | 1073     MapHandleList* receiver_maps, CodeHandleList* handler_stubs, | 
| 1172     CodeHandleList* handler_stubs, |  | 
| 1173     MapHandleList* transitioned_maps) { | 1074     MapHandleList* transitioned_maps) { | 
| 1174   Label miss; | 1075   Label miss; | 
| 1175   __ JumpIfSmi(receiver(), &miss, Label::kNear); | 1076   __ JumpIfSmi(receiver(), &miss, Label::kNear); | 
| 1176 | 1077 | 
| 1177   __ movp(scratch1(), FieldOperand(receiver(), HeapObject::kMapOffset)); | 1078   __ movp(scratch1(), FieldOperand(receiver(), HeapObject::kMapOffset)); | 
| 1178   int receiver_count = receiver_maps->length(); | 1079   int receiver_count = receiver_maps->length(); | 
| 1179   for (int i = 0; i < receiver_count; ++i) { | 1080   for (int i = 0; i < receiver_count; ++i) { | 
| 1180     // Check map and tail call if there's a match | 1081     // Check map and tail call if there's a match | 
| 1181     __ Cmp(scratch1(), receiver_maps->at(i)); | 1082     __ Cmp(scratch1(), receiver_maps->at(i)); | 
| 1182     if (transitioned_maps->at(i).is_null()) { | 1083     if (transitioned_maps->at(i).is_null()) { | 
| 1183       __ j(equal, handler_stubs->at(i), RelocInfo::CODE_TARGET); | 1084       __ j(equal, handler_stubs->at(i), RelocInfo::CODE_TARGET); | 
| 1184     } else { | 1085     } else { | 
| 1185       Label next_map; | 1086       Label next_map; | 
| 1186       __ j(not_equal, &next_map, Label::kNear); | 1087       __ j(not_equal, &next_map, Label::kNear); | 
| 1187       __ Move(transition_map(), | 1088       __ Move(transition_map(), | 
| 1188               transitioned_maps->at(i), | 1089               transitioned_maps->at(i), | 
| 1189               RelocInfo::EMBEDDED_OBJECT); | 1090               RelocInfo::EMBEDDED_OBJECT); | 
| 1190       __ jmp(handler_stubs->at(i), RelocInfo::CODE_TARGET); | 1091       __ jmp(handler_stubs->at(i), RelocInfo::CODE_TARGET); | 
| 1191       __ bind(&next_map); | 1092       __ bind(&next_map); | 
| 1192     } | 1093     } | 
| 1193   } | 1094   } | 
| 1194 | 1095 | 
| 1195   __ bind(&miss); | 1096   __ bind(&miss); | 
| 1196 | 1097 | 
| 1197   TailCallBuiltin(masm(), MissBuiltin(kind())); | 1098   TailCallBuiltin(masm(), MissBuiltin(kind())); | 
| 1198 | 1099 | 
| 1199   // Return the generated code. | 1100   // Return the generated code. | 
| 1200   return GetICCode( | 1101   return GetCode(kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC); | 
| 1201       kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC); |  | 
| 1202 } | 1102 } | 
| 1203 | 1103 | 
| 1204 | 1104 | 
| 1205 Handle<Code> LoadStubCompiler::CompileLoadNonexistent(Handle<HeapType> type, | 1105 Handle<Code> NamedLoadHandlerCompiler::CompileLoadNonexistent( | 
| 1206                                                       Handle<JSObject> last, | 1106     Handle<HeapType> type, Handle<JSObject> last, Handle<Name> name) { | 
| 1207                                                       Handle<Name> name) { | 1107   NonexistentFrontend(type, last, name); | 
| 1208   NonexistentHandlerFrontend(type, last, name); |  | 
| 1209 | 1108 | 
| 1210   // Return undefined if maps of the full prototype chain are still the | 1109   // Return undefined if maps of the full prototype chain are still the | 
| 1211   // same and no global property with this name contains a value. | 1110   // same and no global property with this name contains a value. | 
| 1212   __ LoadRoot(rax, Heap::kUndefinedValueRootIndex); | 1111   __ LoadRoot(rax, Heap::kUndefinedValueRootIndex); | 
| 1213   __ ret(0); | 1112   __ ret(0); | 
| 1214 | 1113 | 
| 1215   // Return the generated code. | 1114   // Return the generated code. | 
| 1216   return GetCode(kind(), Code::FAST, name); | 1115   return GetCode(kind(), Code::FAST, name); | 
| 1217 } | 1116 } | 
| 1218 | 1117 | 
| 1219 | 1118 | 
| 1220 Register* LoadStubCompiler::registers() { | 1119 Register* PropertyAccessCompiler::load_calling_convention() { | 
| 1221   // receiver, name, scratch1, scratch2, scratch3, scratch4. | 1120   // receiver, name, scratch1, scratch2, scratch3, scratch4. | 
| 1222   Register receiver = LoadIC::ReceiverRegister(); | 1121   Register receiver = LoadIC::ReceiverRegister(); | 
| 1223   Register name = LoadIC::NameRegister(); | 1122   Register name = LoadIC::NameRegister(); | 
| 1224   static Register registers[] = { receiver, name, rax, rbx, rdi, r8 }; | 1123   static Register registers[] = { receiver, name, rax, rbx, rdi, r8 }; | 
| 1225   return registers; | 1124   return registers; | 
| 1226 } | 1125 } | 
| 1227 | 1126 | 
| 1228 | 1127 | 
| 1229 Register* KeyedLoadStubCompiler::registers() { | 1128 Register* PropertyAccessCompiler::store_calling_convention() { | 
| 1230   // receiver, name, scratch1, scratch2, scratch3, scratch4. |  | 
| 1231   Register receiver = LoadIC::ReceiverRegister(); |  | 
| 1232   Register name = LoadIC::NameRegister(); |  | 
| 1233   static Register registers[] = { receiver, name, rax, rbx, rdi, r8 }; |  | 
| 1234   return registers; |  | 
| 1235 } |  | 
| 1236 |  | 
| 1237 |  | 
| 1238 Register StoreStubCompiler::value() { |  | 
| 1239   return StoreIC::ValueRegister(); |  | 
| 1240 } |  | 
| 1241 |  | 
| 1242 |  | 
| 1243 Register* StoreStubCompiler::registers() { |  | 
| 1244   // receiver, name, scratch1, scratch2, scratch3. | 1129   // receiver, name, scratch1, scratch2, scratch3. | 
| 1245   Register receiver = KeyedStoreIC::ReceiverRegister(); | 1130   Register receiver = KeyedStoreIC::ReceiverRegister(); | 
| 1246   Register name = KeyedStoreIC::NameRegister(); | 1131   Register name = KeyedStoreIC::NameRegister(); | 
| 1247   static Register registers[] = { receiver, name, rbx, rdi, r8 }; | 1132   static Register registers[] = { receiver, name, rbx, rdi, r8 }; | 
| 1248   return registers; | 1133   return registers; | 
| 1249 } | 1134 } | 
| 1250 | 1135 | 
| 1251 | 1136 | 
| 1252 Register* KeyedStoreStubCompiler::registers() { | 1137 Register* PropertyAccessCompiler::keyed_store_calling_convention() { | 
| 1253   // receiver, name, scratch1/map, scratch2, scratch3. | 1138   // receiver, name, scratch1/map, scratch2, scratch3. | 
| 1254   Register receiver = KeyedStoreIC::ReceiverRegister(); | 1139   Register receiver = KeyedStoreIC::ReceiverRegister(); | 
| 1255   Register name = KeyedStoreIC::NameRegister(); | 1140   Register name = KeyedStoreIC::NameRegister(); | 
| 1256   Register map = KeyedStoreIC::MapRegister(); | 1141   Register map = KeyedStoreIC::MapRegister(); | 
| 1257   static Register registers[] = { receiver, name, map, rdi, r8 }; | 1142   static Register registers[] = { receiver, name, map, rdi, r8 }; | 
| 1258   return registers; | 1143   return registers; | 
| 1259 } | 1144 } | 
| 1260 | 1145 | 
| 1261 | 1146 | 
|  | 1147 Register NamedStoreHandlerCompiler::value() { return StoreIC::ValueRegister(); } | 
|  | 1148 | 
|  | 1149 | 
| 1262 #undef __ | 1150 #undef __ | 
| 1263 #define __ ACCESS_MASM(masm) | 1151 #define __ ACCESS_MASM(masm) | 
| 1264 | 1152 | 
| 1265 | 1153 | 
| 1266 void LoadStubCompiler::GenerateLoadViaGetter(MacroAssembler* masm, | 1154 void NamedLoadHandlerCompiler::GenerateLoadViaGetter( | 
| 1267                                              Handle<HeapType> type, | 1155     MacroAssembler* masm, Handle<HeapType> type, Register receiver, | 
| 1268                                              Register receiver, | 1156     Handle<JSFunction> getter) { | 
| 1269                                              Handle<JSFunction> getter) { |  | 
| 1270   // ----------- S t a t e ------------- | 1157   // ----------- S t a t e ------------- | 
| 1271   //  -- rax    : receiver | 1158   //  -- rax    : receiver | 
| 1272   //  -- rcx    : name | 1159   //  -- rcx    : name | 
| 1273   //  -- rsp[0] : return address | 1160   //  -- rsp[0] : return address | 
| 1274   // ----------------------------------- | 1161   // ----------------------------------- | 
| 1275   { | 1162   { | 
| 1276     FrameScope scope(masm, StackFrame::INTERNAL); | 1163     FrameScope scope(masm, StackFrame::INTERNAL); | 
| 1277 | 1164 | 
| 1278     if (!getter.is_null()) { | 1165     if (!getter.is_null()) { | 
| 1279       // Call the JavaScript getter with the receiver on the stack. | 1166       // Call the JavaScript getter with the receiver on the stack. | 
| (...skipping 17 matching lines...) Expand all  Loading... | 
| 1297     __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 1184     __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 
| 1298   } | 1185   } | 
| 1299   __ ret(0); | 1186   __ ret(0); | 
| 1300 } | 1187 } | 
| 1301 | 1188 | 
| 1302 | 1189 | 
| 1303 #undef __ | 1190 #undef __ | 
| 1304 #define __ ACCESS_MASM(masm()) | 1191 #define __ ACCESS_MASM(masm()) | 
| 1305 | 1192 | 
| 1306 | 1193 | 
| 1307 Handle<Code> LoadStubCompiler::CompileLoadGlobal( | 1194 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal( | 
| 1308     Handle<HeapType> type, | 1195     Handle<HeapType> type, Handle<GlobalObject> global, | 
| 1309     Handle<GlobalObject> global, | 1196     Handle<PropertyCell> cell, Handle<Name> name, bool is_dont_delete) { | 
| 1310     Handle<PropertyCell> cell, |  | 
| 1311     Handle<Name> name, |  | 
| 1312     bool is_dont_delete) { |  | 
| 1313   Label miss; | 1197   Label miss; | 
| 1314   // TODO(verwaest): Directly store to rax. Currently we cannot do this, since | 1198   // TODO(verwaest): Directly store to rax. Currently we cannot do this, since | 
| 1315   // rax is used as receiver(), which we would otherwise clobber before a | 1199   // rax is used as receiver(), which we would otherwise clobber before a | 
| 1316   // potential miss. | 1200   // potential miss. | 
| 1317   HandlerFrontendHeader(type, receiver(), global, name, &miss); | 1201   FrontendHeader(type, receiver(), global, name, &miss); | 
| 1318 | 1202 | 
| 1319   // Get the value from the cell. | 1203   // Get the value from the cell. | 
| 1320   __ Move(rbx, cell); | 1204   __ Move(rbx, cell); | 
| 1321   __ movp(rbx, FieldOperand(rbx, PropertyCell::kValueOffset)); | 1205   __ movp(rbx, FieldOperand(rbx, PropertyCell::kValueOffset)); | 
| 1322 | 1206 | 
| 1323   // Check for deleted property if property can actually be deleted. | 1207   // Check for deleted property if property can actually be deleted. | 
| 1324   if (!is_dont_delete) { | 1208   if (!is_dont_delete) { | 
| 1325     __ CompareRoot(rbx, Heap::kTheHoleValueRootIndex); | 1209     __ CompareRoot(rbx, Heap::kTheHoleValueRootIndex); | 
| 1326     __ j(equal, &miss); | 1210     __ j(equal, &miss); | 
| 1327   } else if (FLAG_debug_code) { | 1211   } else if (FLAG_debug_code) { | 
| 1328     __ CompareRoot(rbx, Heap::kTheHoleValueRootIndex); | 1212     __ CompareRoot(rbx, Heap::kTheHoleValueRootIndex); | 
| 1329     __ Check(not_equal, kDontDeleteCellsCannotContainTheHole); | 1213     __ Check(not_equal, kDontDeleteCellsCannotContainTheHole); | 
| 1330   } | 1214   } | 
| 1331 | 1215 | 
| 1332   Counters* counters = isolate()->counters(); | 1216   Counters* counters = isolate()->counters(); | 
| 1333   __ IncrementCounter(counters->named_load_global_stub(), 1); | 1217   __ IncrementCounter(counters->named_load_global_stub(), 1); | 
| 1334   __ movp(rax, rbx); | 1218   __ movp(rax, rbx); | 
| 1335   __ ret(0); | 1219   __ ret(0); | 
| 1336 | 1220 | 
| 1337   HandlerFrontendFooter(name, &miss); | 1221   FrontendFooter(name, &miss); | 
| 1338 | 1222 | 
| 1339   // Return the generated code. | 1223   // Return the generated code. | 
| 1340   return GetCode(kind(), Code::NORMAL, name); | 1224   return GetCode(kind(), Code::NORMAL, name); | 
| 1341 } | 1225 } | 
| 1342 | 1226 | 
| 1343 | 1227 | 
| 1344 Handle<Code> BaseLoadStoreStubCompiler::CompilePolymorphicIC( | 1228 Handle<Code> PropertyICCompiler::CompilePolymorphic(TypeHandleList* types, | 
| 1345     TypeHandleList* types, | 1229                                                     CodeHandleList* handlers, | 
| 1346     CodeHandleList* handlers, | 1230                                                     Handle<Name> name, | 
| 1347     Handle<Name> name, | 1231                                                     Code::StubType type, | 
| 1348     Code::StubType type, | 1232                                                     IcCheckType check) { | 
| 1349     IcCheckType check) { |  | 
| 1350   Label miss; | 1233   Label miss; | 
| 1351 | 1234 | 
| 1352   if (check == PROPERTY && | 1235   if (check == PROPERTY && | 
| 1353       (kind() == Code::KEYED_LOAD_IC || kind() == Code::KEYED_STORE_IC)) { | 1236       (kind() == Code::KEYED_LOAD_IC || kind() == Code::KEYED_STORE_IC)) { | 
| 1354     __ Cmp(this->name(), name); | 1237     __ Cmp(this->name(), name); | 
| 1355     __ j(not_equal, &miss); | 1238     __ j(not_equal, &miss); | 
| 1356   } | 1239   } | 
| 1357 | 1240 | 
| 1358   Label number_case; | 1241   Label number_case; | 
| 1359   Label* smi_target = IncludesNumberType(types) ? &number_case : &miss; | 1242   Label* smi_target = IncludesNumberType(types) ? &number_case : &miss; | 
| (...skipping 21 matching lines...) Expand all  Loading... | 
| 1381     } | 1264     } | 
| 1382   } | 1265   } | 
| 1383   ASSERT(number_of_handled_maps > 0); | 1266   ASSERT(number_of_handled_maps > 0); | 
| 1384 | 1267 | 
| 1385   __  bind(&miss); | 1268   __  bind(&miss); | 
| 1386   TailCallBuiltin(masm(), MissBuiltin(kind())); | 1269   TailCallBuiltin(masm(), MissBuiltin(kind())); | 
| 1387 | 1270 | 
| 1388   // Return the generated code. | 1271   // Return the generated code. | 
| 1389   InlineCacheState state = | 1272   InlineCacheState state = | 
| 1390       number_of_handled_maps > 1 ? POLYMORPHIC : MONOMORPHIC; | 1273       number_of_handled_maps > 1 ? POLYMORPHIC : MONOMORPHIC; | 
| 1391   return GetICCode(kind(), type, name, state); | 1274   return GetCode(kind(), type, name, state); | 
| 1392 } | 1275 } | 
| 1393 | 1276 | 
| 1394 | 1277 | 
| 1395 #undef __ | 1278 #undef __ | 
| 1396 #define __ ACCESS_MASM(masm) | 1279 #define __ ACCESS_MASM(masm) | 
| 1397 | 1280 | 
| 1398 | 1281 | 
| 1399 void KeyedLoadStubCompiler::GenerateLoadDictionaryElement( | 1282 void IndexedHandlerCompiler::GenerateLoadDictionaryElement( | 
| 1400     MacroAssembler* masm) { | 1283     MacroAssembler* masm) { | 
| 1401   // ----------- S t a t e ------------- | 1284   // ----------- S t a t e ------------- | 
| 1402   //  -- rcx    : key | 1285   //  -- rcx    : key | 
| 1403   //  -- rdx    : receiver | 1286   //  -- rdx    : receiver | 
| 1404   //  -- rsp[0] : return address | 1287   //  -- rsp[0] : return address | 
| 1405   // ----------------------------------- | 1288   // ----------------------------------- | 
| 1406   ASSERT(rdx.is(LoadIC::ReceiverRegister())); | 1289   ASSERT(rdx.is(LoadIC::ReceiverRegister())); | 
| 1407   ASSERT(rcx.is(LoadIC::NameRegister())); | 1290   ASSERT(rcx.is(LoadIC::NameRegister())); | 
| 1408   Label slow, miss; | 1291   Label slow, miss; | 
| 1409 | 1292 | 
| (...skipping 28 matching lines...) Expand all  Loading... | 
| 1438   // ----------------------------------- | 1321   // ----------------------------------- | 
| 1439   TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); | 1322   TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); | 
| 1440 } | 1323 } | 
| 1441 | 1324 | 
| 1442 | 1325 | 
| 1443 #undef __ | 1326 #undef __ | 
| 1444 | 1327 | 
| 1445 } }  // namespace v8::internal | 1328 } }  // namespace v8::internal | 
| 1446 | 1329 | 
| 1447 #endif  // V8_TARGET_ARCH_X64 | 1330 #endif  // V8_TARGET_ARCH_X64 | 
| OLD | NEW | 
|---|