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

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

Issue 427463002: X87: Restructure the IC / Handler compilers (Closed) Base URL: https://chromium.googlesource.com/external/v8.git@bleeding_edge
Patch Set: Created 6 years, 4 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
« no previous file with comments | « src/x87/code-stubs-x87.cc ('k') | no next file » | 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_X87 7 #if V8_TARGET_ARCH_X87
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,
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(
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 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
640 } 570 }
641 571
642 // Return the value (register eax). 572 // Return the value (register eax).
643 ASSERT(value_reg.is(eax)); 573 ASSERT(value_reg.is(eax));
644 __ ret(0); 574 __ ret(0);
645 } 575 }
646 576
647 577
648 // Both name_reg and receiver_reg are preserved on jumps to miss_label, 578 // Both name_reg and receiver_reg are preserved on jumps to miss_label,
649 // but may be destroyed if store is successful. 579 // but may be destroyed if store is successful.
650 void StoreStubCompiler::GenerateStoreField(MacroAssembler* masm, 580 void NamedStoreHandlerCompiler::GenerateStoreField(
651 Handle<JSObject> object, 581 MacroAssembler* masm, Handle<JSObject> object, LookupResult* lookup,
652 LookupResult* lookup, 582 Register receiver_reg, Register name_reg, Register value_reg,
653 Register receiver_reg, 583 Register scratch1, Register scratch2, Label* miss_label) {
654 Register name_reg,
655 Register value_reg,
656 Register scratch1,
657 Register scratch2,
658 Label* miss_label) {
659 // Stub never generated for non-global objects that require access 584 // Stub never generated for non-global objects that require access
660 // checks. 585 // checks.
661 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); 586 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
662 587
663 FieldIndex index = lookup->GetFieldIndex(); 588 FieldIndex index = lookup->GetFieldIndex();
664 589
665 Representation representation = lookup->representation(); 590 Representation representation = lookup->representation();
666 ASSERT(!representation.IsNone()); 591 ASSERT(!representation.IsNone());
667 if (representation.IsSmi()) { 592 if (representation.IsSmi()) {
668 __ JumpIfNotSmi(value_reg, miss_label); 593 __ JumpIfNotSmi(value_reg, miss_label);
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
750 smi_check); 675 smi_check);
751 } 676 }
752 } 677 }
753 678
754 // Return the value (register eax). 679 // Return the value (register eax).
755 ASSERT(value_reg.is(eax)); 680 ASSERT(value_reg.is(eax));
756 __ ret(0); 681 __ ret(0);
757 } 682 }
758 683
759 684
760 void StubCompiler::GenerateTailCall(MacroAssembler* masm, Handle<Code> code) { 685 void PropertyAccessCompiler::GenerateTailCall(MacroAssembler* masm,
686 Handle<Code> code) {
761 __ jmp(code, RelocInfo::CODE_TARGET); 687 __ jmp(code, RelocInfo::CODE_TARGET);
762 } 688 }
763 689
764 690
765 #undef __ 691 #undef __
766 #define __ ACCESS_MASM(masm()) 692 #define __ ACCESS_MASM(masm())
767 693
768 694
769 Register StubCompiler::CheckPrototypes(Handle<HeapType> type, 695 Register PropertyHandlerCompiler::CheckPrototypes(
770 Register object_reg, 696 Handle<HeapType> type, Register object_reg, Handle<JSObject> holder,
771 Handle<JSObject> holder, 697 Register holder_reg, Register scratch1, Register scratch2,
772 Register holder_reg, 698 Handle<Name> name, Label* miss, PrototypeCheckType check) {
773 Register scratch1,
774 Register scratch2,
775 Handle<Name> name,
776 Label* miss,
777 PrototypeCheckType check) {
778 Handle<Map> receiver_map(IC::TypeToMap(*type, isolate())); 699 Handle<Map> receiver_map(IC::TypeToMap(*type, isolate()));
779 700
780 // Make sure there's no overlap between holder and object registers. 701 // Make sure there's no overlap between holder and object registers.
781 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); 702 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg));
782 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) 703 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg)
783 && !scratch2.is(scratch1)); 704 && !scratch2.is(scratch1));
784 705
785 // Keep track of the current object in register reg. 706 // Keep track of the current object in register reg.
786 Register reg = object_reg; 707 Register reg = object_reg;
787 int depth = 0; 708 int depth = 0;
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
874 !current_map->is_access_check_needed()); 795 !current_map->is_access_check_needed());
875 if (current_map->IsJSGlobalProxyMap()) { 796 if (current_map->IsJSGlobalProxyMap()) {
876 __ CheckAccessGlobalProxy(reg, scratch1, scratch2, miss); 797 __ CheckAccessGlobalProxy(reg, scratch1, scratch2, miss);
877 } 798 }
878 799
879 // Return the register containing the holder. 800 // Return the register containing the holder.
880 return reg; 801 return reg;
881 } 802 }
882 803
883 804
884 void LoadStubCompiler::HandlerFrontendFooter(Handle<Name> name, Label* miss) { 805 void NamedLoadHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) {
885 if (!miss->is_unused()) { 806 if (!miss->is_unused()) {
886 Label success; 807 Label success;
887 __ jmp(&success); 808 __ jmp(&success);
888 __ bind(miss); 809 __ bind(miss);
889 TailCallBuiltin(masm(), MissBuiltin(kind())); 810 TailCallBuiltin(masm(), MissBuiltin(kind()));
890 __ bind(&success); 811 __ bind(&success);
891 } 812 }
892 } 813 }
893 814
894 815
895 void StoreStubCompiler::HandlerFrontendFooter(Handle<Name> name, Label* miss) { 816 void NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) {
896 if (!miss->is_unused()) { 817 if (!miss->is_unused()) {
897 Label success; 818 Label success;
898 __ jmp(&success); 819 __ jmp(&success);
899 GenerateRestoreName(masm(), miss, name); 820 GenerateRestoreName(masm(), miss, name);
900 TailCallBuiltin(masm(), MissBuiltin(kind())); 821 TailCallBuiltin(masm(), MissBuiltin(kind()));
901 __ bind(&success); 822 __ bind(&success);
902 } 823 }
903 } 824 }
904 825
905 826
906 Register LoadStubCompiler::CallbackHandlerFrontend( 827 Register NamedLoadHandlerCompiler::CallbackFrontend(Handle<HeapType> type,
907 Handle<HeapType> type, 828 Register object_reg,
908 Register object_reg, 829 Handle<JSObject> holder,
909 Handle<JSObject> holder, 830 Handle<Name> name,
910 Handle<Name> name, 831 Handle<Object> callback) {
911 Handle<Object> callback) {
912 Label miss; 832 Label miss;
913 833
914 Register reg = HandlerFrontendHeader(type, object_reg, holder, name, &miss); 834 Register reg = FrontendHeader(type, object_reg, holder, name, &miss);
915 835
916 if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) { 836 if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) {
917 ASSERT(!reg.is(scratch2())); 837 ASSERT(!reg.is(scratch2()));
918 ASSERT(!reg.is(scratch3())); 838 ASSERT(!reg.is(scratch3()));
919 Register dictionary = scratch1(); 839 Register dictionary = scratch1();
920 bool must_preserve_dictionary_reg = reg.is(dictionary); 840 bool must_preserve_dictionary_reg = reg.is(dictionary);
921 841
922 // Load the properties dictionary. 842 // Load the properties dictionary.
923 if (must_preserve_dictionary_reg) { 843 if (must_preserve_dictionary_reg) {
924 __ push(dictionary); 844 __ push(dictionary);
(...skipping 25 matching lines...) Expand all
950 const int kValueOffset = kElementsStartOffset + kPointerSize; 870 const int kValueOffset = kElementsStartOffset + kPointerSize;
951 __ mov(scratch3(), 871 __ mov(scratch3(),
952 Operand(dictionary, index, times_4, kValueOffset - kHeapObjectTag)); 872 Operand(dictionary, index, times_4, kValueOffset - kHeapObjectTag));
953 if (must_preserve_dictionary_reg) { 873 if (must_preserve_dictionary_reg) {
954 __ pop(dictionary); 874 __ pop(dictionary);
955 } 875 }
956 __ cmp(scratch3(), callback); 876 __ cmp(scratch3(), callback);
957 __ j(not_equal, &miss); 877 __ j(not_equal, &miss);
958 } 878 }
959 879
960 HandlerFrontendFooter(name, &miss); 880 FrontendFooter(name, &miss);
961 return reg; 881 return reg;
962 } 882 }
963 883
964 884
965 void LoadStubCompiler::GenerateLoadField(Register reg, 885 void NamedLoadHandlerCompiler::GenerateLoadField(
966 Handle<JSObject> holder, 886 Register reg, Handle<JSObject> holder, FieldIndex field,
967 FieldIndex field, 887 Representation representation) {
968 Representation representation) {
969 if (!reg.is(receiver())) __ mov(receiver(), reg); 888 if (!reg.is(receiver())) __ mov(receiver(), reg);
970 LoadFieldStub stub(isolate(), field); 889 LoadFieldStub stub(isolate(), field);
971 GenerateTailCall(masm(), stub.GetCode()); 890 GenerateTailCall(masm(), stub.GetCode());
972 } 891 }
973 892
974 893
975 void LoadStubCompiler::GenerateLoadCallback( 894 void NamedLoadHandlerCompiler::GenerateLoadCallback(
976 Register reg, 895 Register reg, Handle<ExecutableAccessorInfo> callback) {
977 Handle<ExecutableAccessorInfo> callback) {
978 // Insert additional parameters into the stack frame above return address. 896 // Insert additional parameters into the stack frame above return address.
979 ASSERT(!scratch3().is(reg)); 897 ASSERT(!scratch3().is(reg));
980 __ pop(scratch3()); // Get return address to place it below. 898 __ pop(scratch3()); // Get return address to place it below.
981 899
982 STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == 0); 900 STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == 0);
983 STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 1); 901 STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 1);
984 STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == 2); 902 STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == 2);
985 STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 3); 903 STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 3);
986 STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == 4); 904 STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == 4);
987 STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 5); 905 STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 5);
(...skipping 23 matching lines...) Expand all
1011 // Abi for CallApiGetter 929 // Abi for CallApiGetter
1012 Register getter_address = edx; 930 Register getter_address = edx;
1013 Address function_address = v8::ToCData<Address>(callback->getter()); 931 Address function_address = v8::ToCData<Address>(callback->getter());
1014 __ mov(getter_address, Immediate(function_address)); 932 __ mov(getter_address, Immediate(function_address));
1015 933
1016 CallApiGetterStub stub(isolate()); 934 CallApiGetterStub stub(isolate());
1017 __ TailCallStub(&stub); 935 __ TailCallStub(&stub);
1018 } 936 }
1019 937
1020 938
1021 void LoadStubCompiler::GenerateLoadConstant(Handle<Object> value) { 939 void NamedLoadHandlerCompiler::GenerateLoadConstant(Handle<Object> value) {
1022 // Return the constant value. 940 // Return the constant value.
1023 __ LoadObject(eax, value); 941 __ LoadObject(eax, value);
1024 __ ret(0); 942 __ ret(0);
1025 } 943 }
1026 944
1027 945
1028 void LoadStubCompiler::GenerateLoadInterceptor( 946 void NamedLoadHandlerCompiler::GenerateLoadInterceptor(
1029 Register holder_reg, 947 Register holder_reg, Handle<Object> object,
1030 Handle<Object> object, 948 Handle<JSObject> interceptor_holder, LookupResult* lookup,
1031 Handle<JSObject> interceptor_holder,
1032 LookupResult* lookup,
1033 Handle<Name> name) { 949 Handle<Name> name) {
1034 ASSERT(interceptor_holder->HasNamedInterceptor()); 950 ASSERT(interceptor_holder->HasNamedInterceptor());
1035 ASSERT(!interceptor_holder->GetNamedInterceptor()->getter()->IsUndefined()); 951 ASSERT(!interceptor_holder->GetNamedInterceptor()->getter()->IsUndefined());
1036 952
1037 // So far the most popular follow ups for interceptor loads are FIELD 953 // So far the most popular follow ups for interceptor loads are FIELD
1038 // and CALLBACKS, so inline only them, other cases may be added 954 // and CALLBACKS, so inline only them, other cases may be added
1039 // later. 955 // later.
1040 bool compile_followup_inline = false; 956 bool compile_followup_inline = false;
1041 if (lookup->IsFound() && lookup->IsCacheable()) { 957 if (lookup->IsFound() && lookup->IsCacheable()) {
1042 if (lookup->IsField()) { 958 if (lookup->IsField()) {
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
1117 __ push(scratch2()); // restore old return address 1033 __ push(scratch2()); // restore old return address
1118 1034
1119 ExternalReference ref = 1035 ExternalReference ref =
1120 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptor), 1036 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptor),
1121 isolate()); 1037 isolate());
1122 __ TailCallExternalReference(ref, StubCache::kInterceptorArgsLength, 1); 1038 __ TailCallExternalReference(ref, StubCache::kInterceptorArgsLength, 1);
1123 } 1039 }
1124 } 1040 }
1125 1041
1126 1042
1127 Handle<Code> StoreStubCompiler::CompileStoreCallback( 1043 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
1128 Handle<JSObject> object, 1044 Handle<JSObject> object, Handle<JSObject> holder, Handle<Name> name,
1129 Handle<JSObject> holder,
1130 Handle<Name> name,
1131 Handle<ExecutableAccessorInfo> callback) { 1045 Handle<ExecutableAccessorInfo> callback) {
1132 Register holder_reg = HandlerFrontend( 1046 Register holder_reg =
1133 IC::CurrentTypeOf(object, isolate()), receiver(), holder, name); 1047 Frontend(IC::CurrentTypeOf(object, isolate()), receiver(), holder, name);
1134 1048
1135 __ pop(scratch1()); // remove the return address 1049 __ pop(scratch1()); // remove the return address
1136 __ push(receiver()); 1050 __ push(receiver());
1137 __ push(holder_reg); 1051 __ push(holder_reg);
1138 __ Push(callback); 1052 __ Push(callback);
1139 __ Push(name); 1053 __ Push(name);
1140 __ push(value()); 1054 __ push(value());
1141 __ push(scratch1()); // restore return address 1055 __ push(scratch1()); // restore return address
1142 1056
1143 // Do tail-call to the runtime system. 1057 // Do tail-call to the runtime system.
1144 ExternalReference store_callback_property = 1058 ExternalReference store_callback_property =
1145 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate()); 1059 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate());
1146 __ TailCallExternalReference(store_callback_property, 5, 1); 1060 __ TailCallExternalReference(store_callback_property, 5, 1);
1147 1061
1148 // Return the generated code. 1062 // Return the generated code.
1149 return GetCode(kind(), Code::FAST, name); 1063 return GetCode(kind(), Code::FAST, name);
1150 } 1064 }
1151 1065
1152 1066
1153 #undef __ 1067 #undef __
1154 #define __ ACCESS_MASM(masm) 1068 #define __ ACCESS_MASM(masm)
1155 1069
1156 1070
1157 void StoreStubCompiler::GenerateStoreViaSetter( 1071 void NamedStoreHandlerCompiler::GenerateStoreViaSetter(
1158 MacroAssembler* masm, 1072 MacroAssembler* masm, Handle<HeapType> type, Register receiver,
1159 Handle<HeapType> type,
1160 Register receiver,
1161 Handle<JSFunction> setter) { 1073 Handle<JSFunction> setter) {
1162 // ----------- S t a t e ------------- 1074 // ----------- S t a t e -------------
1163 // -- esp[0] : return address 1075 // -- esp[0] : return address
1164 // ----------------------------------- 1076 // -----------------------------------
1165 { 1077 {
1166 FrameScope scope(masm, StackFrame::INTERNAL); 1078 FrameScope scope(masm, StackFrame::INTERNAL);
1167 1079
1168 // Save value register, so we can restore it later. 1080 // Save value register, so we can restore it later.
1169 __ push(value()); 1081 __ push(value());
1170 1082
(...skipping 23 matching lines...) Expand all
1194 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 1106 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
1195 } 1107 }
1196 __ ret(0); 1108 __ ret(0);
1197 } 1109 }
1198 1110
1199 1111
1200 #undef __ 1112 #undef __
1201 #define __ ACCESS_MASM(masm()) 1113 #define __ ACCESS_MASM(masm())
1202 1114
1203 1115
1204 Handle<Code> StoreStubCompiler::CompileStoreInterceptor( 1116 Handle<Code> NamedStoreHandlerCompiler::CompileStoreInterceptor(
1205 Handle<JSObject> object, 1117 Handle<JSObject> object, Handle<Name> name) {
1206 Handle<Name> name) {
1207 __ pop(scratch1()); // remove the return address 1118 __ pop(scratch1()); // remove the return address
1208 __ push(receiver()); 1119 __ push(receiver());
1209 __ push(this->name()); 1120 __ push(this->name());
1210 __ push(value()); 1121 __ push(value());
1211 __ push(scratch1()); // restore return address 1122 __ push(scratch1()); // restore return address
1212 1123
1213 // Do tail-call to the runtime system. 1124 // Do tail-call to the runtime system.
1214 ExternalReference store_ic_property = 1125 ExternalReference store_ic_property =
1215 ExternalReference(IC_Utility(IC::kStoreInterceptorProperty), isolate()); 1126 ExternalReference(IC_Utility(IC::kStoreInterceptorProperty), isolate());
1216 __ TailCallExternalReference(store_ic_property, 3, 1); 1127 __ TailCallExternalReference(store_ic_property, 3, 1);
1217 1128
1218 // Return the generated code. 1129 // Return the generated code.
1219 return GetCode(kind(), Code::FAST, name); 1130 return GetCode(kind(), Code::FAST, name);
1220 } 1131 }
1221 1132
1222 1133
1223 void StoreStubCompiler::GenerateStoreArrayLength() { 1134 void NamedStoreHandlerCompiler::GenerateStoreArrayLength() {
1224 // Prepare tail call to StoreIC_ArrayLength. 1135 // Prepare tail call to StoreIC_ArrayLength.
1225 __ pop(scratch1()); // remove the return address 1136 __ pop(scratch1()); // remove the return address
1226 __ push(receiver()); 1137 __ push(receiver());
1227 __ push(value()); 1138 __ push(value());
1228 __ push(scratch1()); // restore return address 1139 __ push(scratch1()); // restore return address
1229 1140
1230 ExternalReference ref = 1141 ExternalReference ref =
1231 ExternalReference(IC_Utility(IC::kStoreIC_ArrayLength), 1142 ExternalReference(IC_Utility(IC::kStoreIC_ArrayLength),
1232 masm()->isolate()); 1143 masm()->isolate());
1233 __ TailCallExternalReference(ref, 2, 1); 1144 __ TailCallExternalReference(ref, 2, 1);
1234 } 1145 }
1235 1146
1236 1147
1237 Handle<Code> KeyedStoreStubCompiler::CompileStorePolymorphic( 1148 Handle<Code> PropertyICCompiler::CompileIndexedStorePolymorphic(
1238 MapHandleList* receiver_maps, 1149 MapHandleList* receiver_maps, CodeHandleList* handler_stubs,
1239 CodeHandleList* handler_stubs,
1240 MapHandleList* transitioned_maps) { 1150 MapHandleList* transitioned_maps) {
1241 Label miss; 1151 Label miss;
1242 __ JumpIfSmi(receiver(), &miss, Label::kNear); 1152 __ JumpIfSmi(receiver(), &miss, Label::kNear);
1243 __ mov(scratch1(), FieldOperand(receiver(), HeapObject::kMapOffset)); 1153 __ mov(scratch1(), FieldOperand(receiver(), HeapObject::kMapOffset));
1244 for (int i = 0; i < receiver_maps->length(); ++i) { 1154 for (int i = 0; i < receiver_maps->length(); ++i) {
1245 __ cmp(scratch1(), receiver_maps->at(i)); 1155 __ cmp(scratch1(), receiver_maps->at(i));
1246 if (transitioned_maps->at(i).is_null()) { 1156 if (transitioned_maps->at(i).is_null()) {
1247 __ j(equal, handler_stubs->at(i)); 1157 __ j(equal, handler_stubs->at(i));
1248 } else { 1158 } else {
1249 Label next_map; 1159 Label next_map;
1250 __ j(not_equal, &next_map, Label::kNear); 1160 __ j(not_equal, &next_map, Label::kNear);
1251 __ mov(transition_map(), Immediate(transitioned_maps->at(i))); 1161 __ mov(transition_map(), Immediate(transitioned_maps->at(i)));
1252 __ jmp(handler_stubs->at(i), RelocInfo::CODE_TARGET); 1162 __ jmp(handler_stubs->at(i), RelocInfo::CODE_TARGET);
1253 __ bind(&next_map); 1163 __ bind(&next_map);
1254 } 1164 }
1255 } 1165 }
1256 __ bind(&miss); 1166 __ bind(&miss);
1257 TailCallBuiltin(masm(), MissBuiltin(kind())); 1167 TailCallBuiltin(masm(), MissBuiltin(kind()));
1258 1168
1259 // Return the generated code. 1169 // Return the generated code.
1260 return GetICCode( 1170 return GetCode(kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC);
1261 kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC);
1262 } 1171 }
1263 1172
1264 1173
1265 Handle<Code> LoadStubCompiler::CompileLoadNonexistent(Handle<HeapType> type, 1174 Handle<Code> NamedLoadHandlerCompiler::CompileLoadNonexistent(
1266 Handle<JSObject> last, 1175 Handle<HeapType> type, Handle<JSObject> last, Handle<Name> name) {
1267 Handle<Name> name) { 1176 NonexistentFrontend(type, last, name);
1268 NonexistentHandlerFrontend(type, last, name);
1269 1177
1270 // Return undefined if maps of the full prototype chain are still the 1178 // Return undefined if maps of the full prototype chain are still the
1271 // same and no global property with this name contains a value. 1179 // same and no global property with this name contains a value.
1272 __ mov(eax, isolate()->factory()->undefined_value()); 1180 __ mov(eax, isolate()->factory()->undefined_value());
1273 __ ret(0); 1181 __ ret(0);
1274 1182
1275 // Return the generated code. 1183 // Return the generated code.
1276 return GetCode(kind(), Code::FAST, name); 1184 return GetCode(kind(), Code::FAST, name);
1277 } 1185 }
1278 1186
1279 1187
1280 Register* LoadStubCompiler::registers() { 1188 Register* PropertyAccessCompiler::load_calling_convention() {
1281 // receiver, name, scratch1, scratch2, scratch3, scratch4. 1189 // receiver, name, scratch1, scratch2, scratch3, scratch4.
1282 Register receiver = LoadIC::ReceiverRegister(); 1190 Register receiver = LoadIC::ReceiverRegister();
1283 Register name = LoadIC::NameRegister(); 1191 Register name = LoadIC::NameRegister();
1284 static Register registers[] = { receiver, name, ebx, eax, edi, no_reg };
1285 return registers;
1286 }
1287
1288
1289 Register* KeyedLoadStubCompiler::registers() {
1290 // receiver, name, scratch1, scratch2, scratch3, scratch4.
1291 Register receiver = LoadIC::ReceiverRegister();
1292 Register name = LoadIC::NameRegister();
1293 static Register registers[] = { receiver, name, ebx, eax, edi, no_reg }; 1192 static Register registers[] = { receiver, name, ebx, eax, edi, no_reg };
1294 return registers; 1193 return registers;
1295 } 1194 }
1296 1195
1297 1196
1298 Register StoreStubCompiler::value() { 1197 Register* PropertyAccessCompiler::store_calling_convention() {
1299 return StoreIC::ValueRegister();
1300 }
1301
1302
1303 Register* StoreStubCompiler::registers() {
1304 // receiver, name, scratch1, scratch2, scratch3. 1198 // receiver, name, scratch1, scratch2, scratch3.
1305 Register receiver = StoreIC::ReceiverRegister(); 1199 Register receiver = StoreIC::ReceiverRegister();
1306 Register name = StoreIC::NameRegister(); 1200 Register name = StoreIC::NameRegister();
1307 static Register registers[] = { receiver, name, ebx, edi, no_reg }; 1201 static Register registers[] = { receiver, name, ebx, edi, no_reg };
1308 return registers; 1202 return registers;
1309 } 1203 }
1310 1204
1311 1205
1312 Register* KeyedStoreStubCompiler::registers() { 1206 Register* PropertyAccessCompiler::keyed_store_calling_convention() {
1313 // receiver, name, scratch1/map, scratch2, scratch3. 1207 // receiver, name, scratch1/map, scratch2, scratch3.
1314 Register receiver = KeyedStoreIC::ReceiverRegister(); 1208 Register receiver = KeyedStoreIC::ReceiverRegister();
1315 Register name = KeyedStoreIC::NameRegister(); 1209 Register name = KeyedStoreIC::NameRegister();
1316 Register map = KeyedStoreIC::MapRegister(); 1210 Register map = KeyedStoreIC::MapRegister();
1317 static Register registers[] = { receiver, name, map, edi, no_reg }; 1211 static Register registers[] = { receiver, name, map, edi, no_reg };
1318 return registers; 1212 return registers;
1319 } 1213 }
1320 1214
1321 1215
1216 Register NamedStoreHandlerCompiler::value() { return StoreIC::ValueRegister(); }
1217
1218
1322 #undef __ 1219 #undef __
1323 #define __ ACCESS_MASM(masm) 1220 #define __ ACCESS_MASM(masm)
1324 1221
1325 1222
1326 void LoadStubCompiler::GenerateLoadViaGetter(MacroAssembler* masm, 1223 void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
1327 Handle<HeapType> type, 1224 MacroAssembler* masm, Handle<HeapType> type, Register receiver,
1328 Register receiver, 1225 Handle<JSFunction> getter) {
1329 Handle<JSFunction> getter) {
1330 { 1226 {
1331 FrameScope scope(masm, StackFrame::INTERNAL); 1227 FrameScope scope(masm, StackFrame::INTERNAL);
1332 1228
1333 if (!getter.is_null()) { 1229 if (!getter.is_null()) {
1334 // Call the JavaScript getter with the receiver on the stack. 1230 // Call the JavaScript getter with the receiver on the stack.
1335 if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) { 1231 if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
1336 // Swap in the global receiver. 1232 // Swap in the global receiver.
1337 __ mov(receiver, 1233 __ mov(receiver,
1338 FieldOperand(receiver, JSGlobalObject::kGlobalProxyOffset)); 1234 FieldOperand(receiver, JSGlobalObject::kGlobalProxyOffset));
1339 } 1235 }
(...skipping 12 matching lines...) Expand all
1352 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 1248 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
1353 } 1249 }
1354 __ ret(0); 1250 __ ret(0);
1355 } 1251 }
1356 1252
1357 1253
1358 #undef __ 1254 #undef __
1359 #define __ ACCESS_MASM(masm()) 1255 #define __ ACCESS_MASM(masm())
1360 1256
1361 1257
1362 Handle<Code> LoadStubCompiler::CompileLoadGlobal( 1258 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal(
1363 Handle<HeapType> type, 1259 Handle<HeapType> type, Handle<GlobalObject> global,
1364 Handle<GlobalObject> global, 1260 Handle<PropertyCell> cell, Handle<Name> name, bool is_dont_delete) {
1365 Handle<PropertyCell> cell,
1366 Handle<Name> name,
1367 bool is_dont_delete) {
1368 Label miss; 1261 Label miss;
1369 1262
1370 HandlerFrontendHeader(type, receiver(), global, name, &miss); 1263 FrontendHeader(type, receiver(), global, name, &miss);
1371 // Get the value from the cell. 1264 // Get the value from the cell.
1372 if (masm()->serializer_enabled()) { 1265 if (masm()->serializer_enabled()) {
1373 __ mov(eax, Immediate(cell)); 1266 __ mov(eax, Immediate(cell));
1374 __ mov(eax, FieldOperand(eax, PropertyCell::kValueOffset)); 1267 __ mov(eax, FieldOperand(eax, PropertyCell::kValueOffset));
1375 } else { 1268 } else {
1376 __ mov(eax, Operand::ForCell(cell)); 1269 __ mov(eax, Operand::ForCell(cell));
1377 } 1270 }
1378 1271
1379 // Check for deleted property if property can actually be deleted. 1272 // Check for deleted property if property can actually be deleted.
1380 if (!is_dont_delete) { 1273 if (!is_dont_delete) {
1381 __ cmp(eax, factory()->the_hole_value()); 1274 __ cmp(eax, factory()->the_hole_value());
1382 __ j(equal, &miss); 1275 __ j(equal, &miss);
1383 } else if (FLAG_debug_code) { 1276 } else if (FLAG_debug_code) {
1384 __ cmp(eax, factory()->the_hole_value()); 1277 __ cmp(eax, factory()->the_hole_value());
1385 __ Check(not_equal, kDontDeleteCellsCannotContainTheHole); 1278 __ Check(not_equal, kDontDeleteCellsCannotContainTheHole);
1386 } 1279 }
1387 1280
1388 Counters* counters = isolate()->counters(); 1281 Counters* counters = isolate()->counters();
1389 __ IncrementCounter(counters->named_load_global_stub(), 1); 1282 __ IncrementCounter(counters->named_load_global_stub(), 1);
1390 // The code above already loads the result into the return register. 1283 // The code above already loads the result into the return register.
1391 __ ret(0); 1284 __ ret(0);
1392 1285
1393 HandlerFrontendFooter(name, &miss); 1286 FrontendFooter(name, &miss);
1394 1287
1395 // Return the generated code. 1288 // Return the generated code.
1396 return GetCode(kind(), Code::NORMAL, name); 1289 return GetCode(kind(), Code::NORMAL, name);
1397 } 1290 }
1398 1291
1399 1292
1400 Handle<Code> BaseLoadStoreStubCompiler::CompilePolymorphicIC( 1293 Handle<Code> PropertyICCompiler::CompilePolymorphic(TypeHandleList* types,
1401 TypeHandleList* types, 1294 CodeHandleList* handlers,
1402 CodeHandleList* handlers, 1295 Handle<Name> name,
1403 Handle<Name> name, 1296 Code::StubType type,
1404 Code::StubType type, 1297 IcCheckType check) {
1405 IcCheckType check) {
1406 Label miss; 1298 Label miss;
1407 1299
1408 if (check == PROPERTY && 1300 if (check == PROPERTY &&
1409 (kind() == Code::KEYED_LOAD_IC || kind() == Code::KEYED_STORE_IC)) { 1301 (kind() == Code::KEYED_LOAD_IC || kind() == Code::KEYED_STORE_IC)) {
1410 __ cmp(this->name(), Immediate(name)); 1302 __ cmp(this->name(), Immediate(name));
1411 __ j(not_equal, &miss); 1303 __ j(not_equal, &miss);
1412 } 1304 }
1413 1305
1414 Label number_case; 1306 Label number_case;
1415 Label* smi_target = IncludesNumberType(types) ? &number_case : &miss; 1307 Label* smi_target = IncludesNumberType(types) ? &number_case : &miss;
(...skipping 20 matching lines...) Expand all
1436 } 1328 }
1437 } 1329 }
1438 ASSERT(number_of_handled_maps != 0); 1330 ASSERT(number_of_handled_maps != 0);
1439 1331
1440 __ bind(&miss); 1332 __ bind(&miss);
1441 TailCallBuiltin(masm(), MissBuiltin(kind())); 1333 TailCallBuiltin(masm(), MissBuiltin(kind()));
1442 1334
1443 // Return the generated code. 1335 // Return the generated code.
1444 InlineCacheState state = 1336 InlineCacheState state =
1445 number_of_handled_maps > 1 ? POLYMORPHIC : MONOMORPHIC; 1337 number_of_handled_maps > 1 ? POLYMORPHIC : MONOMORPHIC;
1446 return GetICCode(kind(), type, name, state); 1338 return GetCode(kind(), type, name, state);
1447 } 1339 }
1448 1340
1449 1341
1450 #undef __ 1342 #undef __
1451 #define __ ACCESS_MASM(masm) 1343 #define __ ACCESS_MASM(masm)
1452 1344
1453 1345
1454 void KeyedLoadStubCompiler::GenerateLoadDictionaryElement( 1346 void IndexedHandlerCompiler::GenerateLoadDictionaryElement(
1455 MacroAssembler* masm) { 1347 MacroAssembler* masm) {
1456 // ----------- S t a t e ------------- 1348 // ----------- S t a t e -------------
1457 // -- ecx : key 1349 // -- ecx : key
1458 // -- edx : receiver 1350 // -- edx : receiver
1459 // -- esp[0] : return address 1351 // -- esp[0] : return address
1460 // ----------------------------------- 1352 // -----------------------------------
1461 ASSERT(edx.is(LoadIC::ReceiverRegister())); 1353 ASSERT(edx.is(LoadIC::ReceiverRegister()));
1462 ASSERT(ecx.is(LoadIC::NameRegister())); 1354 ASSERT(ecx.is(LoadIC::NameRegister()));
1463 Label slow, miss; 1355 Label slow, miss;
1464 1356
(...skipping 30 matching lines...) Expand all
1495 // ----------------------------------- 1387 // -----------------------------------
1496 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); 1388 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
1497 } 1389 }
1498 1390
1499 1391
1500 #undef __ 1392 #undef __
1501 1393
1502 } } // namespace v8::internal 1394 } } // namespace v8::internal
1503 1395
1504 #endif // V8_TARGET_ARCH_X87 1396 #endif // V8_TARGET_ARCH_X87
OLDNEW
« no previous file with comments | « src/x87/code-stubs-x87.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698