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

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

Issue 411973002: Restructure the IC / Handler compilers (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/ia32/code-stubs-ia32.cc ('k') | src/ic.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/ia32/code-stubs-ia32.cc ('k') | src/ic.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698