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_IA32 | 7 #if V8_TARGET_ARCH_IA32 |
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 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
107 __ add(offset, Immediate(Code::kHeaderSize - kHeapObjectTag)); | 107 __ add(offset, Immediate(Code::kHeaderSize - kHeapObjectTag)); |
108 __ jmp(offset); | 108 __ jmp(offset); |
109 | 109 |
110 // Pop at miss. | 110 // Pop at miss. |
111 __ bind(&miss); | 111 __ bind(&miss); |
112 __ pop(offset); | 112 __ pop(offset); |
113 } | 113 } |
114 } | 114 } |
115 | 115 |
116 | 116 |
117 void StubCompiler::GenerateDictionaryNegativeLookup(MacroAssembler* masm, | 117 void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup( |
118 Label* miss_label, | 118 MacroAssembler* masm, Label* miss_label, Register receiver, |
119 Register receiver, | 119 Handle<Name> name, Register scratch0, Register scratch1) { |
120 Handle<Name> name, | |
121 Register scratch0, | |
122 Register scratch1) { | |
123 ASSERT(name->IsUniqueName()); | 120 ASSERT(name->IsUniqueName()); |
124 ASSERT(!receiver.is(scratch0)); | 121 ASSERT(!receiver.is(scratch0)); |
125 Counters* counters = masm->isolate()->counters(); | 122 Counters* counters = masm->isolate()->counters(); |
126 __ IncrementCounter(counters->negative_lookups(), 1); | 123 __ IncrementCounter(counters->negative_lookups(), 1); |
127 __ IncrementCounter(counters->negative_lookups_miss(), 1); | 124 __ IncrementCounter(counters->negative_lookups_miss(), 1); |
128 | 125 |
129 __ mov(scratch0, FieldOperand(receiver, HeapObject::kMapOffset)); | 126 __ mov(scratch0, FieldOperand(receiver, HeapObject::kMapOffset)); |
130 | 127 |
131 const int kInterceptorOrAccessCheckNeededMask = | 128 const int kInterceptorOrAccessCheckNeededMask = |
132 (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded); | 129 (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded); |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
226 ProbeTable( | 223 ProbeTable( |
227 isolate(), masm, flags, kSecondary, name, receiver, offset, extra); | 224 isolate(), masm, flags, kSecondary, name, receiver, offset, extra); |
228 | 225 |
229 // Cache miss: Fall-through and let caller handle the miss by | 226 // Cache miss: Fall-through and let caller handle the miss by |
230 // entering the runtime system. | 227 // entering the runtime system. |
231 __ bind(&miss); | 228 __ bind(&miss); |
232 __ IncrementCounter(counters->megamorphic_stub_cache_misses(), 1); | 229 __ IncrementCounter(counters->megamorphic_stub_cache_misses(), 1); |
233 } | 230 } |
234 | 231 |
235 | 232 |
236 void StubCompiler::GenerateLoadGlobalFunctionPrototype(MacroAssembler* masm, | 233 void NamedLoadHandlerCompiler::GenerateDirectLoadGlobalFunctionPrototype( |
237 int index, | 234 MacroAssembler* masm, int index, Register prototype, Label* miss) { |
238 Register prototype) { | |
239 __ LoadGlobalFunction(index, prototype); | |
240 __ LoadGlobalFunctionInitialMap(prototype, prototype); | |
241 // Load the prototype from the initial map. | |
242 __ mov(prototype, FieldOperand(prototype, Map::kPrototypeOffset)); | |
243 } | |
244 | |
245 | |
246 void StubCompiler::GenerateDirectLoadGlobalFunctionPrototype( | |
247 MacroAssembler* masm, | |
248 int index, | |
249 Register prototype, | |
250 Label* miss) { | |
251 // Get the global function with the given index. | 235 // Get the global function with the given index. |
252 Handle<JSFunction> function( | 236 Handle<JSFunction> function( |
253 JSFunction::cast(masm->isolate()->native_context()->get(index))); | 237 JSFunction::cast(masm->isolate()->native_context()->get(index))); |
254 // Check we're still in the same context. | 238 // Check we're still in the same context. |
255 Register scratch = prototype; | 239 Register scratch = prototype; |
256 const int offset = Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX); | 240 const int offset = Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX); |
257 __ mov(scratch, Operand(esi, offset)); | 241 __ mov(scratch, Operand(esi, offset)); |
258 __ mov(scratch, FieldOperand(scratch, GlobalObject::kNativeContextOffset)); | 242 __ mov(scratch, FieldOperand(scratch, GlobalObject::kNativeContextOffset)); |
259 __ cmp(Operand(scratch, Context::SlotOffset(index)), function); | 243 __ cmp(Operand(scratch, Context::SlotOffset(index)), function); |
260 __ j(not_equal, miss); | 244 __ j(not_equal, miss); |
261 | 245 |
262 // Load its initial map. The global functions all have initial maps. | 246 // Load its initial map. The global functions all have initial maps. |
263 __ Move(prototype, Immediate(Handle<Map>(function->initial_map()))); | 247 __ Move(prototype, Immediate(Handle<Map>(function->initial_map()))); |
264 // Load the prototype from the initial map. | 248 // Load the prototype from the initial map. |
265 __ mov(prototype, FieldOperand(prototype, Map::kPrototypeOffset)); | 249 __ mov(prototype, FieldOperand(prototype, Map::kPrototypeOffset)); |
266 } | 250 } |
267 | 251 |
268 | 252 |
269 void StubCompiler::GenerateLoadArrayLength(MacroAssembler* masm, | 253 void NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype( |
270 Register receiver, | 254 MacroAssembler* masm, Register receiver, Register scratch1, |
271 Register scratch, | 255 Register scratch2, Label* miss_label) { |
272 Label* miss_label) { | |
273 // Check that the receiver isn't a smi. | |
274 __ JumpIfSmi(receiver, miss_label); | |
275 | |
276 // Check that the object is a JS array. | |
277 __ CmpObjectType(receiver, JS_ARRAY_TYPE, scratch); | |
278 __ j(not_equal, miss_label); | |
279 | |
280 // Load length directly from the JS array. | |
281 __ mov(eax, FieldOperand(receiver, JSArray::kLengthOffset)); | |
282 __ ret(0); | |
283 } | |
284 | |
285 | |
286 void StubCompiler::GenerateLoadFunctionPrototype(MacroAssembler* masm, | |
287 Register receiver, | |
288 Register scratch1, | |
289 Register scratch2, | |
290 Label* miss_label) { | |
291 __ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label); | 256 __ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label); |
292 __ mov(eax, scratch1); | 257 __ mov(eax, scratch1); |
293 __ ret(0); | 258 __ ret(0); |
294 } | 259 } |
295 | 260 |
296 | 261 |
297 void StubCompiler::GenerateFastPropertyLoad(MacroAssembler* masm, | |
298 Register dst, | |
299 Register src, | |
300 bool inobject, | |
301 int index, | |
302 Representation representation) { | |
303 ASSERT(!representation.IsDouble()); | |
304 int offset = index * kPointerSize; | |
305 if (!inobject) { | |
306 // Calculate the offset into the properties array. | |
307 offset = offset + FixedArray::kHeaderSize; | |
308 __ mov(dst, FieldOperand(src, JSObject::kPropertiesOffset)); | |
309 src = dst; | |
310 } | |
311 __ mov(dst, FieldOperand(src, offset)); | |
312 } | |
313 | |
314 | |
315 static void PushInterceptorArguments(MacroAssembler* masm, | 262 static void PushInterceptorArguments(MacroAssembler* masm, |
316 Register receiver, | 263 Register receiver, |
317 Register holder, | 264 Register holder, |
318 Register name, | 265 Register name, |
319 Handle<JSObject> holder_obj) { | 266 Handle<JSObject> holder_obj) { |
320 STATIC_ASSERT(StubCache::kInterceptorArgsNameIndex == 0); | 267 STATIC_ASSERT(StubCache::kInterceptorArgsNameIndex == 0); |
321 STATIC_ASSERT(StubCache::kInterceptorArgsInfoIndex == 1); | 268 STATIC_ASSERT(StubCache::kInterceptorArgsInfoIndex == 1); |
322 STATIC_ASSERT(StubCache::kInterceptorArgsThisIndex == 2); | 269 STATIC_ASSERT(StubCache::kInterceptorArgsThisIndex == 2); |
323 STATIC_ASSERT(StubCache::kInterceptorArgsHolderIndex == 3); | 270 STATIC_ASSERT(StubCache::kInterceptorArgsHolderIndex == 3); |
324 STATIC_ASSERT(StubCache::kInterceptorArgsLength == 4); | 271 STATIC_ASSERT(StubCache::kInterceptorArgsLength == 4); |
(...skipping 19 matching lines...) Expand all Loading... | |
344 __ CallExternalReference( | 291 __ CallExternalReference( |
345 ExternalReference(IC_Utility(id), masm->isolate()), | 292 ExternalReference(IC_Utility(id), masm->isolate()), |
346 StubCache::kInterceptorArgsLength); | 293 StubCache::kInterceptorArgsLength); |
347 } | 294 } |
348 | 295 |
349 | 296 |
350 // Generate call to api function. | 297 // Generate call to api function. |
351 // This function uses push() to generate smaller, faster code than | 298 // This function uses push() to generate smaller, faster code than |
352 // the version above. It is an optimization that should will be removed | 299 // the version above. It is an optimization that should will be removed |
353 // when api call ICs are generated in hydrogen. | 300 // when api call ICs are generated in hydrogen. |
354 void StubCompiler::GenerateFastApiCall(MacroAssembler* masm, | 301 void PropertyHandlerCompiler::GenerateFastApiCall( |
355 const CallOptimization& optimization, | 302 MacroAssembler* masm, const CallOptimization& optimization, |
mvstanton
2014/07/24 16:33:47
nit: I like the old style better, what about start
Sven Panne
2014/07/25 06:25:10
This kind of formatting bikeshedding is gone with
| |
356 Handle<Map> receiver_map, | 303 Handle<Map> receiver_map, Register receiver, Register scratch_in, |
357 Register receiver, | 304 bool is_store, int argc, Register* values) { |
358 Register scratch_in, | |
359 bool is_store, | |
360 int argc, | |
361 Register* values) { | |
362 // Copy return value. | 305 // Copy return value. |
363 __ pop(scratch_in); | 306 __ pop(scratch_in); |
364 // receiver | 307 // receiver |
365 __ push(receiver); | 308 __ push(receiver); |
366 // Write the arguments to stack frame. | 309 // Write the arguments to stack frame. |
367 for (int i = 0; i < argc; i++) { | 310 for (int i = 0; i < argc; i++) { |
368 Register arg = values[argc-1-i]; | 311 Register arg = values[argc-1-i]; |
369 ASSERT(!receiver.is(arg)); | 312 ASSERT(!receiver.is(arg)); |
370 ASSERT(!scratch_in.is(arg)); | 313 ASSERT(!scratch_in.is(arg)); |
371 __ push(arg); | 314 __ push(arg); |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
421 // Put api_function_address in place. | 364 // Put api_function_address in place. |
422 Address function_address = v8::ToCData<Address>(api_call_info->callback()); | 365 Address function_address = v8::ToCData<Address>(api_call_info->callback()); |
423 __ mov(api_function_address, Immediate(function_address)); | 366 __ mov(api_function_address, Immediate(function_address)); |
424 | 367 |
425 // Jump to stub. | 368 // Jump to stub. |
426 CallApiFunctionStub stub(isolate, is_store, call_data_undefined, argc); | 369 CallApiFunctionStub stub(isolate, is_store, call_data_undefined, argc); |
427 __ TailCallStub(&stub); | 370 __ TailCallStub(&stub); |
428 } | 371 } |
429 | 372 |
430 | 373 |
431 void StoreStubCompiler::GenerateRestoreName(MacroAssembler* masm, | 374 void NamedStoreHandlerCompiler::GenerateRestoreName(MacroAssembler* masm, |
432 Label* label, | 375 Label* label, |
433 Handle<Name> name) { | 376 Handle<Name> name) { |
434 if (!label->is_unused()) { | 377 if (!label->is_unused()) { |
435 __ bind(label); | 378 __ bind(label); |
436 __ mov(this->name(), Immediate(name)); | 379 __ mov(this->name(), Immediate(name)); |
437 } | 380 } |
438 } | 381 } |
439 | 382 |
440 | 383 |
441 // Generate code to check that a global property cell is empty. Create | 384 // Generate code to check that a global property cell is empty. Create |
442 // the property cell at compilation time if no cell exists for the | 385 // the property cell at compilation time if no cell exists for the |
443 // property. | 386 // property. |
444 void StubCompiler::GenerateCheckPropertyCell(MacroAssembler* masm, | 387 void PropertyHandlerCompiler::GenerateCheckPropertyCell( |
445 Handle<JSGlobalObject> global, | 388 MacroAssembler* masm, Handle<JSGlobalObject> global, Handle<Name> name, |
446 Handle<Name> name, | 389 Register scratch, Label* miss) { |
447 Register scratch, | |
448 Label* miss) { | |
449 Handle<PropertyCell> cell = | 390 Handle<PropertyCell> cell = |
450 JSGlobalObject::EnsurePropertyCell(global, name); | 391 JSGlobalObject::EnsurePropertyCell(global, name); |
451 ASSERT(cell->value()->IsTheHole()); | 392 ASSERT(cell->value()->IsTheHole()); |
452 Handle<Oddball> the_hole = masm->isolate()->factory()->the_hole_value(); | 393 Handle<Oddball> the_hole = masm->isolate()->factory()->the_hole_value(); |
453 if (masm->serializer_enabled()) { | 394 if (masm->serializer_enabled()) { |
454 __ mov(scratch, Immediate(cell)); | 395 __ mov(scratch, Immediate(cell)); |
455 __ cmp(FieldOperand(scratch, PropertyCell::kValueOffset), | 396 __ cmp(FieldOperand(scratch, PropertyCell::kValueOffset), |
456 Immediate(the_hole)); | 397 Immediate(the_hole)); |
457 } else { | 398 } else { |
458 __ cmp(Operand::ForCell(cell), Immediate(the_hole)); | 399 __ cmp(Operand::ForCell(cell), Immediate(the_hole)); |
459 } | 400 } |
460 __ j(not_equal, miss); | 401 __ j(not_equal, miss); |
461 } | 402 } |
462 | 403 |
463 | 404 |
464 void StoreStubCompiler::GenerateNegativeHolderLookup( | 405 void NamedStoreHandlerCompiler::GenerateNegativeHolderLookup( |
465 MacroAssembler* masm, | 406 MacroAssembler* masm, Handle<JSObject> holder, Register holder_reg, |
466 Handle<JSObject> holder, | 407 Handle<Name> name, Label* miss) { |
467 Register holder_reg, | |
468 Handle<Name> name, | |
469 Label* miss) { | |
470 if (holder->IsJSGlobalObject()) { | 408 if (holder->IsJSGlobalObject()) { |
471 GenerateCheckPropertyCell( | 409 GenerateCheckPropertyCell( |
472 masm, Handle<JSGlobalObject>::cast(holder), name, scratch1(), miss); | 410 masm, Handle<JSGlobalObject>::cast(holder), name, scratch1(), miss); |
473 } else if (!holder->HasFastProperties() && !holder->IsJSGlobalProxy()) { | 411 } else if (!holder->HasFastProperties() && !holder->IsJSGlobalProxy()) { |
474 GenerateDictionaryNegativeLookup( | 412 GenerateDictionaryNegativeLookup( |
475 masm, miss, holder_reg, name, scratch1(), scratch2()); | 413 masm, miss, holder_reg, name, scratch1(), scratch2()); |
476 } | 414 } |
477 } | 415 } |
478 | 416 |
479 | 417 |
480 // Receiver_reg is preserved on jumps to miss_label, but may be destroyed if | 418 // Receiver_reg is preserved on jumps to miss_label, but may be destroyed if |
481 // store is successful. | 419 // store is successful. |
482 void StoreStubCompiler::GenerateStoreTransition(MacroAssembler* masm, | 420 void NamedStoreHandlerCompiler::GenerateStoreTransition( |
mvstanton
2014/07/24 16:33:47
Same here, it just hurts my eyes...
| |
483 Handle<JSObject> object, | 421 MacroAssembler* masm, Handle<JSObject> object, LookupResult* lookup, |
484 LookupResult* lookup, | 422 Handle<Map> transition, Handle<Name> name, Register receiver_reg, |
485 Handle<Map> transition, | 423 Register storage_reg, Register value_reg, Register scratch1, |
486 Handle<Name> name, | 424 Register scratch2, Register unused, Label* miss_label, Label* slow) { |
487 Register receiver_reg, | |
488 Register storage_reg, | |
489 Register value_reg, | |
490 Register scratch1, | |
491 Register scratch2, | |
492 Register unused, | |
493 Label* miss_label, | |
494 Label* slow) { | |
495 int descriptor = transition->LastAdded(); | 425 int descriptor = transition->LastAdded(); |
496 DescriptorArray* descriptors = transition->instance_descriptors(); | 426 DescriptorArray* descriptors = transition->instance_descriptors(); |
497 PropertyDetails details = descriptors->GetDetails(descriptor); | 427 PropertyDetails details = descriptors->GetDetails(descriptor); |
498 Representation representation = details.representation(); | 428 Representation representation = details.representation(); |
499 ASSERT(!representation.IsNone()); | 429 ASSERT(!representation.IsNone()); |
500 | 430 |
501 if (details.type() == CONSTANT) { | 431 if (details.type() == CONSTANT) { |
502 Handle<Object> constant(descriptors->GetValue(descriptor), masm->isolate()); | 432 Handle<Object> constant(descriptors->GetValue(descriptor), masm->isolate()); |
503 __ CmpObject(value_reg, constant); | 433 __ CmpObject(value_reg, constant); |
504 __ j(not_equal, miss_label); | 434 __ j(not_equal, miss_label); |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
641 } | 571 } |
642 | 572 |
643 // Return the value (register eax). | 573 // Return the value (register eax). |
644 ASSERT(value_reg.is(eax)); | 574 ASSERT(value_reg.is(eax)); |
645 __ ret(0); | 575 __ ret(0); |
646 } | 576 } |
647 | 577 |
648 | 578 |
649 // Both name_reg and receiver_reg are preserved on jumps to miss_label, | 579 // Both name_reg and receiver_reg are preserved on jumps to miss_label, |
650 // but may be destroyed if store is successful. | 580 // but may be destroyed if store is successful. |
651 void StoreStubCompiler::GenerateStoreField(MacroAssembler* masm, | 581 void NamedStoreHandlerCompiler::GenerateStoreField( |
652 Handle<JSObject> object, | 582 MacroAssembler* masm, Handle<JSObject> object, LookupResult* lookup, |
653 LookupResult* lookup, | 583 Register receiver_reg, Register name_reg, Register value_reg, |
654 Register receiver_reg, | 584 Register scratch1, Register scratch2, Label* miss_label) { |
655 Register name_reg, | |
656 Register value_reg, | |
657 Register scratch1, | |
658 Register scratch2, | |
659 Label* miss_label) { | |
660 // Stub never generated for non-global objects that require access | 585 // Stub never generated for non-global objects that require access |
661 // checks. | 586 // checks. |
662 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); | 587 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); |
663 | 588 |
664 FieldIndex index = lookup->GetFieldIndex(); | 589 FieldIndex index = lookup->GetFieldIndex(); |
665 | 590 |
666 Representation representation = lookup->representation(); | 591 Representation representation = lookup->representation(); |
667 ASSERT(!representation.IsNone()); | 592 ASSERT(!representation.IsNone()); |
668 if (representation.IsSmi()) { | 593 if (representation.IsSmi()) { |
669 __ JumpIfNotSmi(value_reg, miss_label); | 594 __ JumpIfNotSmi(value_reg, miss_label); |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
751 smi_check); | 676 smi_check); |
752 } | 677 } |
753 } | 678 } |
754 | 679 |
755 // Return the value (register eax). | 680 // Return the value (register eax). |
756 ASSERT(value_reg.is(eax)); | 681 ASSERT(value_reg.is(eax)); |
757 __ ret(0); | 682 __ ret(0); |
758 } | 683 } |
759 | 684 |
760 | 685 |
761 void StubCompiler::GenerateTailCall(MacroAssembler* masm, Handle<Code> code) { | 686 void PropertyAccessCompiler::GenerateTailCall(MacroAssembler* masm, |
687 Handle<Code> code) { | |
762 __ jmp(code, RelocInfo::CODE_TARGET); | 688 __ jmp(code, RelocInfo::CODE_TARGET); |
763 } | 689 } |
764 | 690 |
765 | 691 |
766 #undef __ | 692 #undef __ |
767 #define __ ACCESS_MASM(masm()) | 693 #define __ ACCESS_MASM(masm()) |
768 | 694 |
769 | 695 |
770 Register StubCompiler::CheckPrototypes(Handle<HeapType> type, | 696 Register PropertyHandlerCompiler::CheckPrototypes( |
771 Register object_reg, | 697 Handle<HeapType> type, Register object_reg, Handle<JSObject> holder, |
772 Handle<JSObject> holder, | 698 Register holder_reg, Register scratch1, Register scratch2, |
773 Register holder_reg, | 699 Handle<Name> name, Label* miss, PrototypeCheckType check) { |
774 Register scratch1, | |
775 Register scratch2, | |
776 Handle<Name> name, | |
777 Label* miss, | |
778 PrototypeCheckType check) { | |
779 Handle<Map> receiver_map(IC::TypeToMap(*type, isolate())); | 700 Handle<Map> receiver_map(IC::TypeToMap(*type, isolate())); |
780 | 701 |
781 // Make sure there's no overlap between holder and object registers. | 702 // Make sure there's no overlap between holder and object registers. |
782 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); | 703 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); |
783 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) | 704 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) |
784 && !scratch2.is(scratch1)); | 705 && !scratch2.is(scratch1)); |
785 | 706 |
786 // Keep track of the current object in register reg. | 707 // Keep track of the current object in register reg. |
787 Register reg = object_reg; | 708 Register reg = object_reg; |
788 int depth = 0; | 709 int depth = 0; |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
875 !current_map->is_access_check_needed()); | 796 !current_map->is_access_check_needed()); |
876 if (current_map->IsJSGlobalProxyMap()) { | 797 if (current_map->IsJSGlobalProxyMap()) { |
877 __ CheckAccessGlobalProxy(reg, scratch1, scratch2, miss); | 798 __ CheckAccessGlobalProxy(reg, scratch1, scratch2, miss); |
878 } | 799 } |
879 | 800 |
880 // Return the register containing the holder. | 801 // Return the register containing the holder. |
881 return reg; | 802 return reg; |
882 } | 803 } |
883 | 804 |
884 | 805 |
885 void LoadStubCompiler::HandlerFrontendFooter(Handle<Name> name, Label* miss) { | 806 void NamedLoadHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) { |
886 if (!miss->is_unused()) { | 807 if (!miss->is_unused()) { |
887 Label success; | 808 Label success; |
888 __ jmp(&success); | 809 __ jmp(&success); |
889 __ bind(miss); | 810 __ bind(miss); |
890 TailCallBuiltin(masm(), MissBuiltin(kind())); | 811 TailCallBuiltin(masm(), MissBuiltin(kind())); |
891 __ bind(&success); | 812 __ bind(&success); |
892 } | 813 } |
893 } | 814 } |
894 | 815 |
895 | 816 |
896 void StoreStubCompiler::HandlerFrontendFooter(Handle<Name> name, Label* miss) { | 817 void NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) { |
897 if (!miss->is_unused()) { | 818 if (!miss->is_unused()) { |
898 Label success; | 819 Label success; |
899 __ jmp(&success); | 820 __ jmp(&success); |
900 GenerateRestoreName(masm(), miss, name); | 821 GenerateRestoreName(masm(), miss, name); |
901 TailCallBuiltin(masm(), MissBuiltin(kind())); | 822 TailCallBuiltin(masm(), MissBuiltin(kind())); |
902 __ bind(&success); | 823 __ bind(&success); |
903 } | 824 } |
904 } | 825 } |
905 | 826 |
906 | 827 |
907 Register LoadStubCompiler::CallbackHandlerFrontend( | 828 Register NamedLoadHandlerCompiler::CallbackFrontend(Handle<HeapType> type, |
908 Handle<HeapType> type, | 829 Register object_reg, |
909 Register object_reg, | 830 Handle<JSObject> holder, |
910 Handle<JSObject> holder, | 831 Handle<Name> name, |
911 Handle<Name> name, | 832 Handle<Object> callback) { |
912 Handle<Object> callback) { | |
913 Label miss; | 833 Label miss; |
914 | 834 |
915 Register reg = HandlerFrontendHeader(type, object_reg, holder, name, &miss); | 835 Register reg = FrontendHeader(type, object_reg, holder, name, &miss); |
916 | 836 |
917 if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) { | 837 if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) { |
918 ASSERT(!reg.is(scratch2())); | 838 ASSERT(!reg.is(scratch2())); |
919 ASSERT(!reg.is(scratch3())); | 839 ASSERT(!reg.is(scratch3())); |
920 Register dictionary = scratch1(); | 840 Register dictionary = scratch1(); |
921 bool must_preserve_dictionary_reg = reg.is(dictionary); | 841 bool must_preserve_dictionary_reg = reg.is(dictionary); |
922 | 842 |
923 // Load the properties dictionary. | 843 // Load the properties dictionary. |
924 if (must_preserve_dictionary_reg) { | 844 if (must_preserve_dictionary_reg) { |
925 __ push(dictionary); | 845 __ push(dictionary); |
(...skipping 25 matching lines...) Expand all Loading... | |
951 const int kValueOffset = kElementsStartOffset + kPointerSize; | 871 const int kValueOffset = kElementsStartOffset + kPointerSize; |
952 __ mov(scratch3(), | 872 __ mov(scratch3(), |
953 Operand(dictionary, index, times_4, kValueOffset - kHeapObjectTag)); | 873 Operand(dictionary, index, times_4, kValueOffset - kHeapObjectTag)); |
954 if (must_preserve_dictionary_reg) { | 874 if (must_preserve_dictionary_reg) { |
955 __ pop(dictionary); | 875 __ pop(dictionary); |
956 } | 876 } |
957 __ cmp(scratch3(), callback); | 877 __ cmp(scratch3(), callback); |
958 __ j(not_equal, &miss); | 878 __ j(not_equal, &miss); |
959 } | 879 } |
960 | 880 |
961 HandlerFrontendFooter(name, &miss); | 881 FrontendFooter(name, &miss); |
962 return reg; | 882 return reg; |
963 } | 883 } |
964 | 884 |
965 | 885 |
966 void LoadStubCompiler::GenerateLoadField(Register reg, | 886 void NamedLoadHandlerCompiler::GenerateLoadField( |
967 Handle<JSObject> holder, | 887 Register reg, Handle<JSObject> holder, FieldIndex field, |
968 FieldIndex field, | 888 Representation representation) { |
969 Representation representation) { | |
970 if (!reg.is(receiver())) __ mov(receiver(), reg); | 889 if (!reg.is(receiver())) __ mov(receiver(), reg); |
971 LoadFieldStub stub(isolate(), field); | 890 LoadFieldStub stub(isolate(), field); |
972 GenerateTailCall(masm(), stub.GetCode()); | 891 GenerateTailCall(masm(), stub.GetCode()); |
973 } | 892 } |
974 | 893 |
975 | 894 |
976 void LoadStubCompiler::GenerateLoadCallback( | 895 void NamedLoadHandlerCompiler::GenerateLoadCallback( |
977 Register reg, | 896 Register reg, Handle<ExecutableAccessorInfo> callback) { |
978 Handle<ExecutableAccessorInfo> callback) { | |
979 // Insert additional parameters into the stack frame above return address. | 897 // Insert additional parameters into the stack frame above return address. |
980 ASSERT(!scratch3().is(reg)); | 898 ASSERT(!scratch3().is(reg)); |
981 __ pop(scratch3()); // Get return address to place it below. | 899 __ pop(scratch3()); // Get return address to place it below. |
982 | 900 |
983 STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == 0); | 901 STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == 0); |
984 STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 1); | 902 STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 1); |
985 STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == 2); | 903 STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == 2); |
986 STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 3); | 904 STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 3); |
987 STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == 4); | 905 STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == 4); |
988 STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 5); | 906 STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 5); |
(...skipping 23 matching lines...) Expand all Loading... | |
1012 // Abi for CallApiGetter | 930 // Abi for CallApiGetter |
1013 Register getter_address = edx; | 931 Register getter_address = edx; |
1014 Address function_address = v8::ToCData<Address>(callback->getter()); | 932 Address function_address = v8::ToCData<Address>(callback->getter()); |
1015 __ mov(getter_address, Immediate(function_address)); | 933 __ mov(getter_address, Immediate(function_address)); |
1016 | 934 |
1017 CallApiGetterStub stub(isolate()); | 935 CallApiGetterStub stub(isolate()); |
1018 __ TailCallStub(&stub); | 936 __ TailCallStub(&stub); |
1019 } | 937 } |
1020 | 938 |
1021 | 939 |
1022 void LoadStubCompiler::GenerateLoadConstant(Handle<Object> value) { | 940 void NamedLoadHandlerCompiler::GenerateLoadConstant(Handle<Object> value) { |
1023 // Return the constant value. | 941 // Return the constant value. |
1024 __ LoadObject(eax, value); | 942 __ LoadObject(eax, value); |
1025 __ ret(0); | 943 __ ret(0); |
1026 } | 944 } |
1027 | 945 |
1028 | 946 |
1029 void LoadStubCompiler::GenerateLoadInterceptor( | 947 void NamedLoadHandlerCompiler::GenerateLoadInterceptor( |
1030 Register holder_reg, | 948 Register holder_reg, Handle<Object> object, |
1031 Handle<Object> object, | 949 Handle<JSObject> interceptor_holder, LookupResult* lookup, |
1032 Handle<JSObject> interceptor_holder, | |
1033 LookupResult* lookup, | |
1034 Handle<Name> name) { | 950 Handle<Name> name) { |
1035 ASSERT(interceptor_holder->HasNamedInterceptor()); | 951 ASSERT(interceptor_holder->HasNamedInterceptor()); |
1036 ASSERT(!interceptor_holder->GetNamedInterceptor()->getter()->IsUndefined()); | 952 ASSERT(!interceptor_holder->GetNamedInterceptor()->getter()->IsUndefined()); |
1037 | 953 |
1038 // So far the most popular follow ups for interceptor loads are FIELD | 954 // So far the most popular follow ups for interceptor loads are FIELD |
1039 // and CALLBACKS, so inline only them, other cases may be added | 955 // and CALLBACKS, so inline only them, other cases may be added |
1040 // later. | 956 // later. |
1041 bool compile_followup_inline = false; | 957 bool compile_followup_inline = false; |
1042 if (lookup->IsFound() && lookup->IsCacheable()) { | 958 if (lookup->IsFound() && lookup->IsCacheable()) { |
1043 if (lookup->IsField()) { | 959 if (lookup->IsField()) { |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1118 __ push(scratch2()); // restore old return address | 1034 __ push(scratch2()); // restore old return address |
1119 | 1035 |
1120 ExternalReference ref = | 1036 ExternalReference ref = |
1121 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptor), | 1037 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptor), |
1122 isolate()); | 1038 isolate()); |
1123 __ TailCallExternalReference(ref, StubCache::kInterceptorArgsLength, 1); | 1039 __ TailCallExternalReference(ref, StubCache::kInterceptorArgsLength, 1); |
1124 } | 1040 } |
1125 } | 1041 } |
1126 | 1042 |
1127 | 1043 |
1128 Handle<Code> StoreStubCompiler::CompileStoreCallback( | 1044 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback( |
1129 Handle<JSObject> object, | 1045 Handle<JSObject> object, Handle<JSObject> holder, Handle<Name> name, |
1130 Handle<JSObject> holder, | |
1131 Handle<Name> name, | |
1132 Handle<ExecutableAccessorInfo> callback) { | 1046 Handle<ExecutableAccessorInfo> callback) { |
1133 Register holder_reg = HandlerFrontend( | 1047 Register holder_reg = |
1134 IC::CurrentTypeOf(object, isolate()), receiver(), holder, name); | 1048 Frontend(IC::CurrentTypeOf(object, isolate()), receiver(), holder, name); |
1135 | 1049 |
1136 __ pop(scratch1()); // remove the return address | 1050 __ pop(scratch1()); // remove the return address |
1137 __ push(receiver()); | 1051 __ push(receiver()); |
1138 __ push(holder_reg); | 1052 __ push(holder_reg); |
1139 __ Push(callback); | 1053 __ Push(callback); |
1140 __ Push(name); | 1054 __ Push(name); |
1141 __ push(value()); | 1055 __ push(value()); |
1142 __ push(scratch1()); // restore return address | 1056 __ push(scratch1()); // restore return address |
1143 | 1057 |
1144 // Do tail-call to the runtime system. | 1058 // Do tail-call to the runtime system. |
1145 ExternalReference store_callback_property = | 1059 ExternalReference store_callback_property = |
1146 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate()); | 1060 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate()); |
1147 __ TailCallExternalReference(store_callback_property, 5, 1); | 1061 __ TailCallExternalReference(store_callback_property, 5, 1); |
1148 | 1062 |
1149 // Return the generated code. | 1063 // Return the generated code. |
1150 return GetCode(kind(), Code::FAST, name); | 1064 return GetCode(kind(), Code::FAST, name); |
1151 } | 1065 } |
1152 | 1066 |
1153 | 1067 |
1154 #undef __ | 1068 #undef __ |
1155 #define __ ACCESS_MASM(masm) | 1069 #define __ ACCESS_MASM(masm) |
1156 | 1070 |
1157 | 1071 |
1158 void StoreStubCompiler::GenerateStoreViaSetter( | 1072 void NamedStoreHandlerCompiler::GenerateStoreViaSetter( |
1159 MacroAssembler* masm, | 1073 MacroAssembler* masm, Handle<HeapType> type, Register receiver, |
1160 Handle<HeapType> type, | |
1161 Register receiver, | |
1162 Handle<JSFunction> setter) { | 1074 Handle<JSFunction> setter) { |
1163 // ----------- S t a t e ------------- | 1075 // ----------- S t a t e ------------- |
1164 // -- esp[0] : return address | 1076 // -- esp[0] : return address |
1165 // ----------------------------------- | 1077 // ----------------------------------- |
1166 { | 1078 { |
1167 FrameScope scope(masm, StackFrame::INTERNAL); | 1079 FrameScope scope(masm, StackFrame::INTERNAL); |
1168 | 1080 |
1169 // Save value register, so we can restore it later. | 1081 // Save value register, so we can restore it later. |
1170 __ push(value()); | 1082 __ push(value()); |
1171 | 1083 |
(...skipping 23 matching lines...) Expand all Loading... | |
1195 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 1107 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
1196 } | 1108 } |
1197 __ ret(0); | 1109 __ ret(0); |
1198 } | 1110 } |
1199 | 1111 |
1200 | 1112 |
1201 #undef __ | 1113 #undef __ |
1202 #define __ ACCESS_MASM(masm()) | 1114 #define __ ACCESS_MASM(masm()) |
1203 | 1115 |
1204 | 1116 |
1205 Handle<Code> StoreStubCompiler::CompileStoreInterceptor( | 1117 Handle<Code> NamedStoreHandlerCompiler::CompileStoreInterceptor( |
1206 Handle<JSObject> object, | 1118 Handle<JSObject> object, Handle<Name> name) { |
1207 Handle<Name> name) { | |
1208 __ pop(scratch1()); // remove the return address | 1119 __ pop(scratch1()); // remove the return address |
1209 __ push(receiver()); | 1120 __ push(receiver()); |
1210 __ push(this->name()); | 1121 __ push(this->name()); |
1211 __ push(value()); | 1122 __ push(value()); |
1212 __ push(scratch1()); // restore return address | 1123 __ push(scratch1()); // restore return address |
1213 | 1124 |
1214 // Do tail-call to the runtime system. | 1125 // Do tail-call to the runtime system. |
1215 ExternalReference store_ic_property = | 1126 ExternalReference store_ic_property = |
1216 ExternalReference(IC_Utility(IC::kStoreInterceptorProperty), isolate()); | 1127 ExternalReference(IC_Utility(IC::kStoreInterceptorProperty), isolate()); |
1217 __ TailCallExternalReference(store_ic_property, 3, 1); | 1128 __ TailCallExternalReference(store_ic_property, 3, 1); |
1218 | 1129 |
1219 // Return the generated code. | 1130 // Return the generated code. |
1220 return GetCode(kind(), Code::FAST, name); | 1131 return GetCode(kind(), Code::FAST, name); |
1221 } | 1132 } |
1222 | 1133 |
1223 | 1134 |
1224 void StoreStubCompiler::GenerateStoreArrayLength() { | 1135 void NamedStoreHandlerCompiler::GenerateStoreArrayLength() { |
1225 // Prepare tail call to StoreIC_ArrayLength. | 1136 // Prepare tail call to StoreIC_ArrayLength. |
1226 __ pop(scratch1()); // remove the return address | 1137 __ pop(scratch1()); // remove the return address |
1227 __ push(receiver()); | 1138 __ push(receiver()); |
1228 __ push(value()); | 1139 __ push(value()); |
1229 __ push(scratch1()); // restore return address | 1140 __ push(scratch1()); // restore return address |
1230 | 1141 |
1231 ExternalReference ref = | 1142 ExternalReference ref = |
1232 ExternalReference(IC_Utility(IC::kStoreIC_ArrayLength), | 1143 ExternalReference(IC_Utility(IC::kStoreIC_ArrayLength), |
1233 masm()->isolate()); | 1144 masm()->isolate()); |
1234 __ TailCallExternalReference(ref, 2, 1); | 1145 __ TailCallExternalReference(ref, 2, 1); |
1235 } | 1146 } |
1236 | 1147 |
1237 | 1148 |
1238 Handle<Code> KeyedStoreStubCompiler::CompileStorePolymorphic( | 1149 Handle<Code> PropertyICCompiler::CompileIndexedStorePolymorphic( |
1239 MapHandleList* receiver_maps, | 1150 MapHandleList* receiver_maps, CodeHandleList* handler_stubs, |
1240 CodeHandleList* handler_stubs, | |
1241 MapHandleList* transitioned_maps) { | 1151 MapHandleList* transitioned_maps) { |
1242 Label miss; | 1152 Label miss; |
1243 __ JumpIfSmi(receiver(), &miss, Label::kNear); | 1153 __ JumpIfSmi(receiver(), &miss, Label::kNear); |
1244 __ mov(scratch1(), FieldOperand(receiver(), HeapObject::kMapOffset)); | 1154 __ mov(scratch1(), FieldOperand(receiver(), HeapObject::kMapOffset)); |
1245 for (int i = 0; i < receiver_maps->length(); ++i) { | 1155 for (int i = 0; i < receiver_maps->length(); ++i) { |
1246 __ cmp(scratch1(), receiver_maps->at(i)); | 1156 __ cmp(scratch1(), receiver_maps->at(i)); |
1247 if (transitioned_maps->at(i).is_null()) { | 1157 if (transitioned_maps->at(i).is_null()) { |
1248 __ j(equal, handler_stubs->at(i)); | 1158 __ j(equal, handler_stubs->at(i)); |
1249 } else { | 1159 } else { |
1250 Label next_map; | 1160 Label next_map; |
1251 __ j(not_equal, &next_map, Label::kNear); | 1161 __ j(not_equal, &next_map, Label::kNear); |
1252 __ mov(transition_map(), Immediate(transitioned_maps->at(i))); | 1162 __ mov(transition_map(), Immediate(transitioned_maps->at(i))); |
1253 __ jmp(handler_stubs->at(i), RelocInfo::CODE_TARGET); | 1163 __ jmp(handler_stubs->at(i), RelocInfo::CODE_TARGET); |
1254 __ bind(&next_map); | 1164 __ bind(&next_map); |
1255 } | 1165 } |
1256 } | 1166 } |
1257 __ bind(&miss); | 1167 __ bind(&miss); |
1258 TailCallBuiltin(masm(), MissBuiltin(kind())); | 1168 TailCallBuiltin(masm(), MissBuiltin(kind())); |
1259 | 1169 |
1260 // Return the generated code. | 1170 // Return the generated code. |
1261 return GetICCode( | 1171 return GetCode(kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC); |
1262 kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC); | |
1263 } | 1172 } |
1264 | 1173 |
1265 | 1174 |
1266 Handle<Code> LoadStubCompiler::CompileLoadNonexistent(Handle<HeapType> type, | 1175 Handle<Code> NamedLoadHandlerCompiler::CompileLoadNonexistent( |
1267 Handle<JSObject> last, | 1176 Handle<HeapType> type, Handle<JSObject> last, Handle<Name> name) { |
1268 Handle<Name> name) { | 1177 NonexistentFrontend(type, last, name); |
1269 NonexistentHandlerFrontend(type, last, name); | |
1270 | 1178 |
1271 // Return undefined if maps of the full prototype chain are still the | 1179 // Return undefined if maps of the full prototype chain are still the |
1272 // same and no global property with this name contains a value. | 1180 // same and no global property with this name contains a value. |
1273 __ mov(eax, isolate()->factory()->undefined_value()); | 1181 __ mov(eax, isolate()->factory()->undefined_value()); |
1274 __ ret(0); | 1182 __ ret(0); |
1275 | 1183 |
1276 // Return the generated code. | 1184 // Return the generated code. |
1277 return GetCode(kind(), Code::FAST, name); | 1185 return GetCode(kind(), Code::FAST, name); |
1278 } | 1186 } |
1279 | 1187 |
1280 | 1188 |
1281 Register* LoadStubCompiler::registers() { | 1189 Register* PropertyAccessCompiler::load_calling_convention() { |
1282 // receiver, name, scratch1, scratch2, scratch3, scratch4. | 1190 // receiver, name, scratch1, scratch2, scratch3, scratch4. |
1283 Register receiver = LoadIC::ReceiverRegister(); | 1191 Register receiver = LoadIC::ReceiverRegister(); |
1284 Register name = LoadIC::NameRegister(); | 1192 Register name = LoadIC::NameRegister(); |
1285 static Register registers[] = { receiver, name, ebx, eax, edi, no_reg }; | |
1286 return registers; | |
1287 } | |
1288 | |
1289 | |
1290 Register* KeyedLoadStubCompiler::registers() { | |
1291 // receiver, name, scratch1, scratch2, scratch3, scratch4. | |
1292 Register receiver = LoadIC::ReceiverRegister(); | |
1293 Register name = LoadIC::NameRegister(); | |
1294 static Register registers[] = { receiver, name, ebx, eax, edi, no_reg }; | 1193 static Register registers[] = { receiver, name, ebx, eax, edi, no_reg }; |
1295 return registers; | 1194 return registers; |
1296 } | 1195 } |
1297 | 1196 |
1298 | 1197 |
1299 Register StoreStubCompiler::value() { | 1198 Register* PropertyAccessCompiler::store_calling_convention() { |
1300 return StoreIC::ValueRegister(); | |
1301 } | |
1302 | |
1303 | |
1304 Register* StoreStubCompiler::registers() { | |
1305 // receiver, name, scratch1, scratch2, scratch3. | 1199 // receiver, name, scratch1, scratch2, scratch3. |
1306 Register receiver = StoreIC::ReceiverRegister(); | 1200 Register receiver = StoreIC::ReceiverRegister(); |
1307 Register name = StoreIC::NameRegister(); | 1201 Register name = StoreIC::NameRegister(); |
1308 static Register registers[] = { receiver, name, ebx, edi, no_reg }; | 1202 static Register registers[] = { receiver, name, ebx, edi, no_reg }; |
1309 return registers; | 1203 return registers; |
1310 } | 1204 } |
1311 | 1205 |
1312 | 1206 |
1313 Register* KeyedStoreStubCompiler::registers() { | 1207 Register* PropertyAccessCompiler::keyed_store_calling_convention() { |
1314 // receiver, name, scratch1/map, scratch2, scratch3. | 1208 // receiver, name, scratch1/map, scratch2, scratch3. |
1315 Register receiver = KeyedStoreIC::ReceiverRegister(); | 1209 Register receiver = KeyedStoreIC::ReceiverRegister(); |
1316 Register name = KeyedStoreIC::NameRegister(); | 1210 Register name = KeyedStoreIC::NameRegister(); |
1317 Register map = KeyedStoreIC::MapRegister(); | 1211 Register map = KeyedStoreIC::MapRegister(); |
1318 static Register registers[] = { receiver, name, map, edi, no_reg }; | 1212 static Register registers[] = { receiver, name, map, edi, no_reg }; |
1319 return registers; | 1213 return registers; |
1320 } | 1214 } |
1321 | 1215 |
1322 | 1216 |
1217 Register NamedStoreHandlerCompiler::value() { return StoreIC::ValueRegister(); } | |
1218 | |
1219 | |
1323 #undef __ | 1220 #undef __ |
1324 #define __ ACCESS_MASM(masm) | 1221 #define __ ACCESS_MASM(masm) |
1325 | 1222 |
1326 | 1223 |
1327 void LoadStubCompiler::GenerateLoadViaGetter(MacroAssembler* masm, | 1224 void NamedLoadHandlerCompiler::GenerateLoadViaGetter( |
1328 Handle<HeapType> type, | 1225 MacroAssembler* masm, Handle<HeapType> type, Register receiver, |
1329 Register receiver, | 1226 Handle<JSFunction> getter) { |
1330 Handle<JSFunction> getter) { | |
1331 { | 1227 { |
1332 FrameScope scope(masm, StackFrame::INTERNAL); | 1228 FrameScope scope(masm, StackFrame::INTERNAL); |
1333 | 1229 |
1334 if (!getter.is_null()) { | 1230 if (!getter.is_null()) { |
1335 // Call the JavaScript getter with the receiver on the stack. | 1231 // Call the JavaScript getter with the receiver on the stack. |
1336 if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) { | 1232 if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) { |
1337 // Swap in the global receiver. | 1233 // Swap in the global receiver. |
1338 __ mov(receiver, | 1234 __ mov(receiver, |
1339 FieldOperand(receiver, JSGlobalObject::kGlobalProxyOffset)); | 1235 FieldOperand(receiver, JSGlobalObject::kGlobalProxyOffset)); |
1340 } | 1236 } |
(...skipping 12 matching lines...) Expand all Loading... | |
1353 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 1249 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
1354 } | 1250 } |
1355 __ ret(0); | 1251 __ ret(0); |
1356 } | 1252 } |
1357 | 1253 |
1358 | 1254 |
1359 #undef __ | 1255 #undef __ |
1360 #define __ ACCESS_MASM(masm()) | 1256 #define __ ACCESS_MASM(masm()) |
1361 | 1257 |
1362 | 1258 |
1363 Handle<Code> LoadStubCompiler::CompileLoadGlobal( | 1259 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal( |
1364 Handle<HeapType> type, | 1260 Handle<HeapType> type, Handle<GlobalObject> global, |
1365 Handle<GlobalObject> global, | 1261 Handle<PropertyCell> cell, Handle<Name> name, bool is_dont_delete) { |
1366 Handle<PropertyCell> cell, | |
1367 Handle<Name> name, | |
1368 bool is_dont_delete) { | |
1369 Label miss; | 1262 Label miss; |
1370 | 1263 |
1371 HandlerFrontendHeader(type, receiver(), global, name, &miss); | 1264 FrontendHeader(type, receiver(), global, name, &miss); |
1372 // Get the value from the cell. | 1265 // Get the value from the cell. |
1373 if (masm()->serializer_enabled()) { | 1266 if (masm()->serializer_enabled()) { |
1374 __ mov(eax, Immediate(cell)); | 1267 __ mov(eax, Immediate(cell)); |
1375 __ mov(eax, FieldOperand(eax, PropertyCell::kValueOffset)); | 1268 __ mov(eax, FieldOperand(eax, PropertyCell::kValueOffset)); |
1376 } else { | 1269 } else { |
1377 __ mov(eax, Operand::ForCell(cell)); | 1270 __ mov(eax, Operand::ForCell(cell)); |
1378 } | 1271 } |
1379 | 1272 |
1380 // Check for deleted property if property can actually be deleted. | 1273 // Check for deleted property if property can actually be deleted. |
1381 if (!is_dont_delete) { | 1274 if (!is_dont_delete) { |
1382 __ cmp(eax, factory()->the_hole_value()); | 1275 __ cmp(eax, factory()->the_hole_value()); |
1383 __ j(equal, &miss); | 1276 __ j(equal, &miss); |
1384 } else if (FLAG_debug_code) { | 1277 } else if (FLAG_debug_code) { |
1385 __ cmp(eax, factory()->the_hole_value()); | 1278 __ cmp(eax, factory()->the_hole_value()); |
1386 __ Check(not_equal, kDontDeleteCellsCannotContainTheHole); | 1279 __ Check(not_equal, kDontDeleteCellsCannotContainTheHole); |
1387 } | 1280 } |
1388 | 1281 |
1389 Counters* counters = isolate()->counters(); | 1282 Counters* counters = isolate()->counters(); |
1390 __ IncrementCounter(counters->named_load_global_stub(), 1); | 1283 __ IncrementCounter(counters->named_load_global_stub(), 1); |
1391 // The code above already loads the result into the return register. | 1284 // The code above already loads the result into the return register. |
1392 __ ret(0); | 1285 __ ret(0); |
1393 | 1286 |
1394 HandlerFrontendFooter(name, &miss); | 1287 FrontendFooter(name, &miss); |
1395 | 1288 |
1396 // Return the generated code. | 1289 // Return the generated code. |
1397 return GetCode(kind(), Code::NORMAL, name); | 1290 return GetCode(kind(), Code::NORMAL, name); |
1398 } | 1291 } |
1399 | 1292 |
1400 | 1293 |
1401 Handle<Code> BaseLoadStoreStubCompiler::CompilePolymorphicIC( | 1294 Handle<Code> PropertyICCompiler::CompilePolymorphic(TypeHandleList* types, |
1402 TypeHandleList* types, | 1295 CodeHandleList* handlers, |
1403 CodeHandleList* handlers, | 1296 Handle<Name> name, |
1404 Handle<Name> name, | 1297 Code::StubType type, |
1405 Code::StubType type, | 1298 IcCheckType check) { |
1406 IcCheckType check) { | |
1407 Label miss; | 1299 Label miss; |
1408 | 1300 |
1409 if (check == PROPERTY && | 1301 if (check == PROPERTY && |
1410 (kind() == Code::KEYED_LOAD_IC || kind() == Code::KEYED_STORE_IC)) { | 1302 (kind() == Code::KEYED_LOAD_IC || kind() == Code::KEYED_STORE_IC)) { |
1411 __ cmp(this->name(), Immediate(name)); | 1303 __ cmp(this->name(), Immediate(name)); |
1412 __ j(not_equal, &miss); | 1304 __ j(not_equal, &miss); |
1413 } | 1305 } |
1414 | 1306 |
1415 Label number_case; | 1307 Label number_case; |
1416 Label* smi_target = IncludesNumberType(types) ? &number_case : &miss; | 1308 Label* smi_target = IncludesNumberType(types) ? &number_case : &miss; |
(...skipping 20 matching lines...) Expand all Loading... | |
1437 } | 1329 } |
1438 } | 1330 } |
1439 ASSERT(number_of_handled_maps != 0); | 1331 ASSERT(number_of_handled_maps != 0); |
1440 | 1332 |
1441 __ bind(&miss); | 1333 __ bind(&miss); |
1442 TailCallBuiltin(masm(), MissBuiltin(kind())); | 1334 TailCallBuiltin(masm(), MissBuiltin(kind())); |
1443 | 1335 |
1444 // Return the generated code. | 1336 // Return the generated code. |
1445 InlineCacheState state = | 1337 InlineCacheState state = |
1446 number_of_handled_maps > 1 ? POLYMORPHIC : MONOMORPHIC; | 1338 number_of_handled_maps > 1 ? POLYMORPHIC : MONOMORPHIC; |
1447 return GetICCode(kind(), type, name, state); | 1339 return GetCode(kind(), type, name, state); |
1448 } | 1340 } |
1449 | 1341 |
1450 | 1342 |
1451 #undef __ | 1343 #undef __ |
1452 #define __ ACCESS_MASM(masm) | 1344 #define __ ACCESS_MASM(masm) |
1453 | 1345 |
1454 | 1346 |
1455 void KeyedLoadStubCompiler::GenerateLoadDictionaryElement( | 1347 void IndexedHandlerCompiler::GenerateLoadDictionaryElement( |
1456 MacroAssembler* masm) { | 1348 MacroAssembler* masm) { |
1457 // ----------- S t a t e ------------- | 1349 // ----------- S t a t e ------------- |
1458 // -- ecx : key | 1350 // -- ecx : key |
1459 // -- edx : receiver | 1351 // -- edx : receiver |
1460 // -- esp[0] : return address | 1352 // -- esp[0] : return address |
1461 // ----------------------------------- | 1353 // ----------------------------------- |
1462 ASSERT(edx.is(LoadIC::ReceiverRegister())); | 1354 ASSERT(edx.is(LoadIC::ReceiverRegister())); |
1463 ASSERT(ecx.is(LoadIC::NameRegister())); | 1355 ASSERT(ecx.is(LoadIC::NameRegister())); |
1464 Label slow, miss; | 1356 Label slow, miss; |
1465 | 1357 |
(...skipping 30 matching lines...) Expand all Loading... | |
1496 // ----------------------------------- | 1388 // ----------------------------------- |
1497 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); | 1389 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); |
1498 } | 1390 } |
1499 | 1391 |
1500 | 1392 |
1501 #undef __ | 1393 #undef __ |
1502 | 1394 |
1503 } } // namespace v8::internal | 1395 } } // namespace v8::internal |
1504 | 1396 |
1505 #endif // V8_TARGET_ARCH_IA32 | 1397 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |