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

Side by Side Diff: src/arm/stub-cache-arm.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
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_ARM 7 #if V8_TARGET_ARCH_ARM
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 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
91 #endif 91 #endif
92 92
93 // Jump to the first instruction in the code stub. 93 // Jump to the first instruction in the code stub.
94 __ add(pc, code, Operand(Code::kHeaderSize - kHeapObjectTag)); 94 __ add(pc, code, Operand(Code::kHeaderSize - kHeapObjectTag));
95 95
96 // Miss: fall through. 96 // Miss: fall through.
97 __ bind(&miss); 97 __ bind(&miss);
98 } 98 }
99 99
100 100
101 void StubCompiler::GenerateDictionaryNegativeLookup(MacroAssembler* masm, 101 void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup(
102 Label* miss_label, 102 MacroAssembler* masm, Label* miss_label, Register receiver,
103 Register receiver, 103 Handle<Name> name, Register scratch0, Register scratch1) {
104 Handle<Name> name,
105 Register scratch0,
106 Register scratch1) {
107 ASSERT(name->IsUniqueName()); 104 ASSERT(name->IsUniqueName());
108 ASSERT(!receiver.is(scratch0)); 105 ASSERT(!receiver.is(scratch0));
109 Counters* counters = masm->isolate()->counters(); 106 Counters* counters = masm->isolate()->counters();
110 __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1); 107 __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1);
111 __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); 108 __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1);
112 109
113 Label done; 110 Label done;
114 111
115 const int kInterceptorOrAccessCheckNeededMask = 112 const int kInterceptorOrAccessCheckNeededMask =
116 (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded); 113 (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded);
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
240 extra3); 237 extra3);
241 238
242 // Cache miss: Fall-through and let caller handle the miss by 239 // Cache miss: Fall-through and let caller handle the miss by
243 // entering the runtime system. 240 // entering the runtime system.
244 __ bind(&miss); 241 __ bind(&miss);
245 __ IncrementCounter(counters->megamorphic_stub_cache_misses(), 1, 242 __ IncrementCounter(counters->megamorphic_stub_cache_misses(), 1,
246 extra2, extra3); 243 extra2, extra3);
247 } 244 }
248 245
249 246
250 void StubCompiler::GenerateLoadGlobalFunctionPrototype(MacroAssembler* masm, 247 void NamedLoadHandlerCompiler::GenerateDirectLoadGlobalFunctionPrototype(
251 int index, 248 MacroAssembler* masm, int index, Register prototype, Label* miss) {
252 Register prototype) {
253 // Load the global or builtins object from the current context.
254 __ ldr(prototype,
255 MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
256 // Load the native context from the global or builtins object.
257 __ ldr(prototype,
258 FieldMemOperand(prototype, GlobalObject::kNativeContextOffset));
259 // Load the function from the native context.
260 __ ldr(prototype, MemOperand(prototype, Context::SlotOffset(index)));
261 // Load the initial map. The global functions all have initial maps.
262 __ ldr(prototype,
263 FieldMemOperand(prototype, JSFunction::kPrototypeOrInitialMapOffset));
264 // Load the prototype from the initial map.
265 __ ldr(prototype, FieldMemOperand(prototype, Map::kPrototypeOffset));
266 }
267
268
269 void StubCompiler::GenerateDirectLoadGlobalFunctionPrototype(
270 MacroAssembler* masm,
271 int index,
272 Register prototype,
273 Label* miss) {
274 Isolate* isolate = masm->isolate(); 249 Isolate* isolate = masm->isolate();
275 // Get the global function with the given index. 250 // Get the global function with the given index.
276 Handle<JSFunction> function( 251 Handle<JSFunction> function(
277 JSFunction::cast(isolate->native_context()->get(index))); 252 JSFunction::cast(isolate->native_context()->get(index)));
278 253
279 // Check we're still in the same context. 254 // Check we're still in the same context.
280 Register scratch = prototype; 255 Register scratch = prototype;
281 const int offset = Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX); 256 const int offset = Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX);
282 __ ldr(scratch, MemOperand(cp, offset)); 257 __ ldr(scratch, MemOperand(cp, offset));
283 __ ldr(scratch, FieldMemOperand(scratch, GlobalObject::kNativeContextOffset)); 258 __ ldr(scratch, FieldMemOperand(scratch, GlobalObject::kNativeContextOffset));
284 __ ldr(scratch, MemOperand(scratch, Context::SlotOffset(index))); 259 __ ldr(scratch, MemOperand(scratch, Context::SlotOffset(index)));
285 __ Move(ip, function); 260 __ Move(ip, function);
286 __ cmp(ip, scratch); 261 __ cmp(ip, scratch);
287 __ b(ne, miss); 262 __ b(ne, miss);
288 263
289 // Load its initial map. The global functions all have initial maps. 264 // Load its initial map. The global functions all have initial maps.
290 __ Move(prototype, Handle<Map>(function->initial_map())); 265 __ Move(prototype, Handle<Map>(function->initial_map()));
291 // Load the prototype from the initial map. 266 // Load the prototype from the initial map.
292 __ ldr(prototype, FieldMemOperand(prototype, Map::kPrototypeOffset)); 267 __ ldr(prototype, FieldMemOperand(prototype, Map::kPrototypeOffset));
293 } 268 }
294 269
295 270
296 void StubCompiler::GenerateFastPropertyLoad(MacroAssembler* masm, 271 void NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(
297 Register dst, 272 MacroAssembler* masm, Register receiver, Register scratch1,
298 Register src, 273 Register scratch2, Label* miss_label) {
299 bool inobject,
300 int index,
301 Representation representation) {
302 ASSERT(!representation.IsDouble());
303 int offset = index * kPointerSize;
304 if (!inobject) {
305 // Calculate the offset into the properties array.
306 offset = offset + FixedArray::kHeaderSize;
307 __ ldr(dst, FieldMemOperand(src, JSObject::kPropertiesOffset));
308 src = dst;
309 }
310 __ ldr(dst, FieldMemOperand(src, offset));
311 }
312
313
314 void StubCompiler::GenerateLoadArrayLength(MacroAssembler* masm,
315 Register receiver,
316 Register scratch,
317 Label* miss_label) {
318 // Check that the receiver isn't a smi.
319 __ JumpIfSmi(receiver, miss_label);
320
321 // Check that the object is a JS array.
322 __ CompareObjectType(receiver, scratch, scratch, JS_ARRAY_TYPE);
323 __ b(ne, miss_label);
324
325 // Load length directly from the JS array.
326 __ ldr(r0, FieldMemOperand(receiver, JSArray::kLengthOffset));
327 __ Ret();
328 }
329
330
331 void StubCompiler::GenerateLoadFunctionPrototype(MacroAssembler* masm,
332 Register receiver,
333 Register scratch1,
334 Register scratch2,
335 Label* miss_label) {
336 __ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label); 274 __ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label);
337 __ mov(r0, scratch1); 275 __ mov(r0, scratch1);
338 __ Ret(); 276 __ Ret();
339 } 277 }
340 278
341 279
342 // Generate code to check that a global property cell is empty. Create 280 // Generate code to check that a global property cell is empty. Create
343 // the property cell at compilation time if no cell exists for the 281 // the property cell at compilation time if no cell exists for the
344 // property. 282 // property.
345 void StubCompiler::GenerateCheckPropertyCell(MacroAssembler* masm, 283 void PropertyHandlerCompiler::GenerateCheckPropertyCell(
346 Handle<JSGlobalObject> global, 284 MacroAssembler* masm, Handle<JSGlobalObject> global, Handle<Name> name,
347 Handle<Name> name, 285 Register scratch, Label* miss) {
348 Register scratch,
349 Label* miss) {
350 Handle<Cell> cell = JSGlobalObject::EnsurePropertyCell(global, name); 286 Handle<Cell> cell = JSGlobalObject::EnsurePropertyCell(global, name);
351 ASSERT(cell->value()->IsTheHole()); 287 ASSERT(cell->value()->IsTheHole());
352 __ mov(scratch, Operand(cell)); 288 __ mov(scratch, Operand(cell));
353 __ ldr(scratch, FieldMemOperand(scratch, Cell::kValueOffset)); 289 __ ldr(scratch, FieldMemOperand(scratch, Cell::kValueOffset));
354 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); 290 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
355 __ cmp(scratch, ip); 291 __ cmp(scratch, ip);
356 __ b(ne, miss); 292 __ b(ne, miss);
357 } 293 }
358 294
359 295
360 void StoreStubCompiler::GenerateNegativeHolderLookup( 296 void NamedStoreHandlerCompiler::GenerateNegativeHolderLookup(
361 MacroAssembler* masm, 297 MacroAssembler* masm, Handle<JSObject> holder, Register holder_reg,
362 Handle<JSObject> holder, 298 Handle<Name> name, Label* miss) {
363 Register holder_reg,
364 Handle<Name> name,
365 Label* miss) {
366 if (holder->IsJSGlobalObject()) { 299 if (holder->IsJSGlobalObject()) {
367 GenerateCheckPropertyCell( 300 GenerateCheckPropertyCell(
368 masm, Handle<JSGlobalObject>::cast(holder), name, scratch1(), miss); 301 masm, Handle<JSGlobalObject>::cast(holder), name, scratch1(), miss);
369 } else if (!holder->HasFastProperties() && !holder->IsJSGlobalProxy()) { 302 } else if (!holder->HasFastProperties() && !holder->IsJSGlobalProxy()) {
370 GenerateDictionaryNegativeLookup( 303 GenerateDictionaryNegativeLookup(
371 masm, miss, holder_reg, name, scratch1(), scratch2()); 304 masm, miss, holder_reg, name, scratch1(), scratch2());
372 } 305 }
373 } 306 }
374 307
375 308
376 // Generate StoreTransition code, value is passed in r0 register. 309 // Generate StoreTransition code, value is passed in r0 register.
377 // When leaving generated code after success, the receiver_reg and name_reg 310 // When leaving generated code after success, the receiver_reg and name_reg
378 // may be clobbered. Upon branch to miss_label, the receiver and name 311 // may be clobbered. Upon branch to miss_label, the receiver and name
379 // registers have their original values. 312 // registers have their original values.
380 void StoreStubCompiler::GenerateStoreTransition(MacroAssembler* masm, 313 void NamedStoreHandlerCompiler::GenerateStoreTransition(
381 Handle<JSObject> object, 314 MacroAssembler* masm, Handle<JSObject> object, LookupResult* lookup,
382 LookupResult* lookup, 315 Handle<Map> transition, Handle<Name> name, Register receiver_reg,
383 Handle<Map> transition, 316 Register storage_reg, Register value_reg, Register scratch1,
384 Handle<Name> name, 317 Register scratch2, Register scratch3, Label* miss_label, Label* slow) {
385 Register receiver_reg,
386 Register storage_reg,
387 Register value_reg,
388 Register scratch1,
389 Register scratch2,
390 Register scratch3,
391 Label* miss_label,
392 Label* slow) {
393 // r0 : value 318 // r0 : value
394 Label exit; 319 Label exit;
395 320
396 int descriptor = transition->LastAdded(); 321 int descriptor = transition->LastAdded();
397 DescriptorArray* descriptors = transition->instance_descriptors(); 322 DescriptorArray* descriptors = transition->instance_descriptors();
398 PropertyDetails details = descriptors->GetDetails(descriptor); 323 PropertyDetails details = descriptors->GetDetails(descriptor);
399 Representation representation = details.representation(); 324 Representation representation = details.representation();
400 ASSERT(!representation.IsNone()); 325 ASSERT(!representation.IsNone());
401 326
402 if (details.type() == CONSTANT) { 327 if (details.type() == CONSTANT) {
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
551 ASSERT(value_reg.is(r0)); 476 ASSERT(value_reg.is(r0));
552 __ bind(&exit); 477 __ bind(&exit);
553 __ Ret(); 478 __ Ret();
554 } 479 }
555 480
556 481
557 // Generate StoreField code, value is passed in r0 register. 482 // Generate StoreField code, value is passed in r0 register.
558 // When leaving generated code after success, the receiver_reg and name_reg 483 // When leaving generated code after success, the receiver_reg and name_reg
559 // may be clobbered. Upon branch to miss_label, the receiver and name 484 // may be clobbered. Upon branch to miss_label, the receiver and name
560 // registers have their original values. 485 // registers have their original values.
561 void StoreStubCompiler::GenerateStoreField(MacroAssembler* masm, 486 void NamedStoreHandlerCompiler::GenerateStoreField(
562 Handle<JSObject> object, 487 MacroAssembler* masm, Handle<JSObject> object, LookupResult* lookup,
563 LookupResult* lookup, 488 Register receiver_reg, Register name_reg, Register value_reg,
564 Register receiver_reg, 489 Register scratch1, Register scratch2, Label* miss_label) {
565 Register name_reg,
566 Register value_reg,
567 Register scratch1,
568 Register scratch2,
569 Label* miss_label) {
570 // r0 : value 490 // r0 : value
571 Label exit; 491 Label exit;
572 492
573 // Stub never generated for non-global objects that require access 493 // Stub never generated for non-global objects that require access
574 // checks. 494 // checks.
575 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); 495 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
576 496
577 FieldIndex index = lookup->GetFieldIndex(); 497 FieldIndex index = lookup->GetFieldIndex();
578 498
579 Representation representation = lookup->representation(); 499 Representation representation = lookup->representation();
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
677 } 597 }
678 } 598 }
679 599
680 // Return the value (register r0). 600 // Return the value (register r0).
681 ASSERT(value_reg.is(r0)); 601 ASSERT(value_reg.is(r0));
682 __ bind(&exit); 602 __ bind(&exit);
683 __ Ret(); 603 __ Ret();
684 } 604 }
685 605
686 606
687 void StoreStubCompiler::GenerateRestoreName(MacroAssembler* masm, 607 void NamedStoreHandlerCompiler::GenerateRestoreName(MacroAssembler* masm,
688 Label* label, 608 Label* label,
689 Handle<Name> name) { 609 Handle<Name> name) {
690 if (!label->is_unused()) { 610 if (!label->is_unused()) {
691 __ bind(label); 611 __ bind(label);
692 __ mov(this->name(), Operand(name)); 612 __ mov(this->name(), Operand(name));
693 } 613 }
694 } 614 }
695 615
696 616
697 static void PushInterceptorArguments(MacroAssembler* masm, 617 static void PushInterceptorArguments(MacroAssembler* masm,
698 Register receiver, 618 Register receiver,
699 Register holder, 619 Register holder,
(...skipping 23 matching lines...) Expand all
723 Handle<JSObject> holder_obj, 643 Handle<JSObject> holder_obj,
724 IC::UtilityId id) { 644 IC::UtilityId id) {
725 PushInterceptorArguments(masm, receiver, holder, name, holder_obj); 645 PushInterceptorArguments(masm, receiver, holder, name, holder_obj);
726 __ CallExternalReference( 646 __ CallExternalReference(
727 ExternalReference(IC_Utility(id), masm->isolate()), 647 ExternalReference(IC_Utility(id), masm->isolate()),
728 StubCache::kInterceptorArgsLength); 648 StubCache::kInterceptorArgsLength);
729 } 649 }
730 650
731 651
732 // Generate call to api function. 652 // Generate call to api function.
733 void StubCompiler::GenerateFastApiCall(MacroAssembler* masm, 653 void PropertyHandlerCompiler::GenerateFastApiCall(
734 const CallOptimization& optimization, 654 MacroAssembler* masm, const CallOptimization& optimization,
735 Handle<Map> receiver_map, 655 Handle<Map> receiver_map, Register receiver, Register scratch_in,
736 Register receiver, 656 bool is_store, int argc, Register* values) {
737 Register scratch_in,
738 bool is_store,
739 int argc,
740 Register* values) {
741 ASSERT(!receiver.is(scratch_in)); 657 ASSERT(!receiver.is(scratch_in));
742 __ push(receiver); 658 __ push(receiver);
743 // Write the arguments to stack frame. 659 // Write the arguments to stack frame.
744 for (int i = 0; i < argc; i++) { 660 for (int i = 0; i < argc; i++) {
745 Register arg = values[argc-1-i]; 661 Register arg = values[argc-1-i];
746 ASSERT(!receiver.is(arg)); 662 ASSERT(!receiver.is(arg));
747 ASSERT(!scratch_in.is(arg)); 663 ASSERT(!scratch_in.is(arg));
748 __ push(arg); 664 __ push(arg);
749 } 665 }
750 ASSERT(optimization.is_simple_api_call()); 666 ASSERT(optimization.is_simple_api_call());
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
800 type, 716 type,
801 masm->isolate()); 717 masm->isolate());
802 __ mov(api_function_address, Operand(ref)); 718 __ mov(api_function_address, Operand(ref));
803 719
804 // Jump to stub. 720 // Jump to stub.
805 CallApiFunctionStub stub(isolate, is_store, call_data_undefined, argc); 721 CallApiFunctionStub stub(isolate, is_store, call_data_undefined, argc);
806 __ TailCallStub(&stub); 722 __ TailCallStub(&stub);
807 } 723 }
808 724
809 725
810 void StubCompiler::GenerateTailCall(MacroAssembler* masm, Handle<Code> code) { 726 void PropertyAccessCompiler::GenerateTailCall(MacroAssembler* masm,
727 Handle<Code> code) {
811 __ Jump(code, RelocInfo::CODE_TARGET); 728 __ Jump(code, RelocInfo::CODE_TARGET);
812 } 729 }
813 730
814 731
815 #undef __ 732 #undef __
816 #define __ ACCESS_MASM(masm()) 733 #define __ ACCESS_MASM(masm())
817 734
818 735
819 Register StubCompiler::CheckPrototypes(Handle<HeapType> type, 736 Register PropertyHandlerCompiler::CheckPrototypes(
820 Register object_reg, 737 Handle<HeapType> type, Register object_reg, Handle<JSObject> holder,
821 Handle<JSObject> holder, 738 Register holder_reg, Register scratch1, Register scratch2,
822 Register holder_reg, 739 Handle<Name> name, Label* miss, PrototypeCheckType check) {
823 Register scratch1,
824 Register scratch2,
825 Handle<Name> name,
826 Label* miss,
827 PrototypeCheckType check) {
828 Handle<Map> receiver_map(IC::TypeToMap(*type, isolate())); 740 Handle<Map> receiver_map(IC::TypeToMap(*type, isolate()));
829 741
830 // Make sure there's no overlap between holder and object registers. 742 // Make sure there's no overlap between holder and object registers.
831 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); 743 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg));
832 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) 744 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg)
833 && !scratch2.is(scratch1)); 745 && !scratch2.is(scratch1));
834 746
835 // Keep track of the current object in register reg. 747 // Keep track of the current object in register reg.
836 Register reg = object_reg; 748 Register reg = object_reg;
837 int depth = 0; 749 int depth = 0;
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
924 !current_map->is_access_check_needed()); 836 !current_map->is_access_check_needed());
925 if (current_map->IsJSGlobalProxyMap()) { 837 if (current_map->IsJSGlobalProxyMap()) {
926 __ CheckAccessGlobalProxy(reg, scratch1, miss); 838 __ CheckAccessGlobalProxy(reg, scratch1, miss);
927 } 839 }
928 840
929 // Return the register containing the holder. 841 // Return the register containing the holder.
930 return reg; 842 return reg;
931 } 843 }
932 844
933 845
934 void LoadStubCompiler::HandlerFrontendFooter(Handle<Name> name, Label* miss) { 846 void NamedLoadHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) {
935 if (!miss->is_unused()) { 847 if (!miss->is_unused()) {
936 Label success; 848 Label success;
937 __ b(&success); 849 __ b(&success);
938 __ bind(miss); 850 __ bind(miss);
939 TailCallBuiltin(masm(), MissBuiltin(kind())); 851 TailCallBuiltin(masm(), MissBuiltin(kind()));
940 __ bind(&success); 852 __ bind(&success);
941 } 853 }
942 } 854 }
943 855
944 856
945 void StoreStubCompiler::HandlerFrontendFooter(Handle<Name> name, Label* miss) { 857 void NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) {
946 if (!miss->is_unused()) { 858 if (!miss->is_unused()) {
947 Label success; 859 Label success;
948 __ b(&success); 860 __ b(&success);
949 GenerateRestoreName(masm(), miss, name); 861 GenerateRestoreName(masm(), miss, name);
950 TailCallBuiltin(masm(), MissBuiltin(kind())); 862 TailCallBuiltin(masm(), MissBuiltin(kind()));
951 __ bind(&success); 863 __ bind(&success);
952 } 864 }
953 } 865 }
954 866
955 867
956 Register LoadStubCompiler::CallbackHandlerFrontend( 868 Register NamedLoadHandlerCompiler::CallbackFrontend(Handle<HeapType> type,
957 Handle<HeapType> type, 869 Register object_reg,
958 Register object_reg, 870 Handle<JSObject> holder,
959 Handle<JSObject> holder, 871 Handle<Name> name,
960 Handle<Name> name, 872 Handle<Object> callback) {
961 Handle<Object> callback) {
962 Label miss; 873 Label miss;
963 874
964 Register reg = HandlerFrontendHeader(type, object_reg, holder, name, &miss); 875 Register reg = FrontendHeader(type, object_reg, holder, name, &miss);
965 876
966 if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) { 877 if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) {
967 ASSERT(!reg.is(scratch2())); 878 ASSERT(!reg.is(scratch2()));
968 ASSERT(!reg.is(scratch3())); 879 ASSERT(!reg.is(scratch3()));
969 ASSERT(!reg.is(scratch4())); 880 ASSERT(!reg.is(scratch4()));
970 881
971 // Load the properties dictionary. 882 // Load the properties dictionary.
972 Register dictionary = scratch4(); 883 Register dictionary = scratch4();
973 __ ldr(dictionary, FieldMemOperand(reg, JSObject::kPropertiesOffset)); 884 __ ldr(dictionary, FieldMemOperand(reg, JSObject::kPropertiesOffset));
974 885
(...skipping 12 matching lines...) Expand all
987 // pointer into the dictionary. Check that the value is the callback. 898 // pointer into the dictionary. Check that the value is the callback.
988 Register pointer = scratch3(); 899 Register pointer = scratch3();
989 const int kElementsStartOffset = NameDictionary::kHeaderSize + 900 const int kElementsStartOffset = NameDictionary::kHeaderSize +
990 NameDictionary::kElementsStartIndex * kPointerSize; 901 NameDictionary::kElementsStartIndex * kPointerSize;
991 const int kValueOffset = kElementsStartOffset + kPointerSize; 902 const int kValueOffset = kElementsStartOffset + kPointerSize;
992 __ ldr(scratch2(), FieldMemOperand(pointer, kValueOffset)); 903 __ ldr(scratch2(), FieldMemOperand(pointer, kValueOffset));
993 __ cmp(scratch2(), Operand(callback)); 904 __ cmp(scratch2(), Operand(callback));
994 __ b(ne, &miss); 905 __ b(ne, &miss);
995 } 906 }
996 907
997 HandlerFrontendFooter(name, &miss); 908 FrontendFooter(name, &miss);
998 return reg; 909 return reg;
999 } 910 }
1000 911
1001 912
1002 void LoadStubCompiler::GenerateLoadField(Register reg, 913 void NamedLoadHandlerCompiler::GenerateLoadField(
1003 Handle<JSObject> holder, 914 Register reg, Handle<JSObject> holder, FieldIndex field,
1004 FieldIndex field, 915 Representation representation) {
1005 Representation representation) {
1006 if (!reg.is(receiver())) __ mov(receiver(), reg); 916 if (!reg.is(receiver())) __ mov(receiver(), reg);
1007 LoadFieldStub stub(isolate(), field); 917 LoadFieldStub stub(isolate(), field);
1008 GenerateTailCall(masm(), stub.GetCode()); 918 GenerateTailCall(masm(), stub.GetCode());
1009 } 919 }
1010 920
1011 921
1012 void LoadStubCompiler::GenerateLoadConstant(Handle<Object> value) { 922 void NamedLoadHandlerCompiler::GenerateLoadConstant(Handle<Object> value) {
1013 // Return the constant value. 923 // Return the constant value.
1014 __ Move(r0, value); 924 __ Move(r0, value);
1015 __ Ret(); 925 __ Ret();
1016 } 926 }
1017 927
1018 928
1019 void LoadStubCompiler::GenerateLoadCallback( 929 void NamedLoadHandlerCompiler::GenerateLoadCallback(
1020 Register reg, 930 Register reg, Handle<ExecutableAccessorInfo> callback) {
1021 Handle<ExecutableAccessorInfo> callback) {
1022 // Build AccessorInfo::args_ list on the stack and push property name below 931 // Build AccessorInfo::args_ list on the stack and push property name below
1023 // the exit frame to make GC aware of them and store pointers to them. 932 // the exit frame to make GC aware of them and store pointers to them.
1024 STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == 0); 933 STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == 0);
1025 STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 1); 934 STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 1);
1026 STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == 2); 935 STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == 2);
1027 STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 3); 936 STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 3);
1028 STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == 4); 937 STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == 4);
1029 STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 5); 938 STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 5);
1030 STATIC_ASSERT(PropertyCallbackArguments::kArgsLength == 6); 939 STATIC_ASSERT(PropertyCallbackArguments::kArgsLength == 6);
1031 ASSERT(!scratch2().is(reg)); 940 ASSERT(!scratch2().is(reg));
(...skipping 24 matching lines...) Expand all
1056 ApiFunction fun(getter_address); 965 ApiFunction fun(getter_address);
1057 ExternalReference::Type type = ExternalReference::DIRECT_GETTER_CALL; 966 ExternalReference::Type type = ExternalReference::DIRECT_GETTER_CALL;
1058 ExternalReference ref = ExternalReference(&fun, type, isolate()); 967 ExternalReference ref = ExternalReference(&fun, type, isolate());
1059 __ mov(getter_address_reg, Operand(ref)); 968 __ mov(getter_address_reg, Operand(ref));
1060 969
1061 CallApiGetterStub stub(isolate()); 970 CallApiGetterStub stub(isolate());
1062 __ TailCallStub(&stub); 971 __ TailCallStub(&stub);
1063 } 972 }
1064 973
1065 974
1066 void LoadStubCompiler::GenerateLoadInterceptor( 975 void NamedLoadHandlerCompiler::GenerateLoadInterceptor(
1067 Register holder_reg, 976 Register holder_reg, Handle<Object> object,
1068 Handle<Object> object, 977 Handle<JSObject> interceptor_holder, LookupResult* lookup,
1069 Handle<JSObject> interceptor_holder,
1070 LookupResult* lookup,
1071 Handle<Name> name) { 978 Handle<Name> name) {
1072 ASSERT(interceptor_holder->HasNamedInterceptor()); 979 ASSERT(interceptor_holder->HasNamedInterceptor());
1073 ASSERT(!interceptor_holder->GetNamedInterceptor()->getter()->IsUndefined()); 980 ASSERT(!interceptor_holder->GetNamedInterceptor()->getter()->IsUndefined());
1074 981
1075 // So far the most popular follow ups for interceptor loads are FIELD 982 // So far the most popular follow ups for interceptor loads are FIELD
1076 // and CALLBACKS, so inline only them, other cases may be added 983 // and CALLBACKS, so inline only them, other cases may be added
1077 // later. 984 // later.
1078 bool compile_followup_inline = false; 985 bool compile_followup_inline = false;
1079 if (lookup->IsFound() && lookup->IsCacheable()) { 986 if (lookup->IsFound() && lookup->IsCacheable()) {
1080 if (lookup->IsField()) { 987 if (lookup->IsField()) {
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
1144 this->name(), interceptor_holder); 1051 this->name(), interceptor_holder);
1145 1052
1146 ExternalReference ref = 1053 ExternalReference ref =
1147 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptor), 1054 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptor),
1148 isolate()); 1055 isolate());
1149 __ TailCallExternalReference(ref, StubCache::kInterceptorArgsLength, 1); 1056 __ TailCallExternalReference(ref, StubCache::kInterceptorArgsLength, 1);
1150 } 1057 }
1151 } 1058 }
1152 1059
1153 1060
1154 Handle<Code> StoreStubCompiler::CompileStoreCallback( 1061 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
1155 Handle<JSObject> object, 1062 Handle<JSObject> object, Handle<JSObject> holder, Handle<Name> name,
1156 Handle<JSObject> holder,
1157 Handle<Name> name,
1158 Handle<ExecutableAccessorInfo> callback) { 1063 Handle<ExecutableAccessorInfo> callback) {
1159 Register holder_reg = HandlerFrontend( 1064 Register holder_reg =
1160 IC::CurrentTypeOf(object, isolate()), receiver(), holder, name); 1065 Frontend(IC::CurrentTypeOf(object, isolate()), receiver(), holder, name);
1161 1066
1162 // Stub never generated for non-global objects that require access checks. 1067 // Stub never generated for non-global objects that require access checks.
1163 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); 1068 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded());
1164 1069
1165 __ push(receiver()); // receiver 1070 __ push(receiver()); // receiver
1166 __ push(holder_reg); 1071 __ push(holder_reg);
1167 __ mov(ip, Operand(callback)); // callback info 1072 __ mov(ip, Operand(callback)); // callback info
1168 __ push(ip); 1073 __ push(ip);
1169 __ mov(ip, Operand(name)); 1074 __ mov(ip, Operand(name));
1170 __ Push(ip, value()); 1075 __ Push(ip, value());
1171 1076
1172 // Do tail-call to the runtime system. 1077 // Do tail-call to the runtime system.
1173 ExternalReference store_callback_property = 1078 ExternalReference store_callback_property =
1174 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate()); 1079 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate());
1175 __ TailCallExternalReference(store_callback_property, 5, 1); 1080 __ TailCallExternalReference(store_callback_property, 5, 1);
1176 1081
1177 // Return the generated code. 1082 // Return the generated code.
1178 return GetCode(kind(), Code::FAST, name); 1083 return GetCode(kind(), Code::FAST, name);
1179 } 1084 }
1180 1085
1181 1086
1182 #undef __ 1087 #undef __
1183 #define __ ACCESS_MASM(masm) 1088 #define __ ACCESS_MASM(masm)
1184 1089
1185 1090
1186 void StoreStubCompiler::GenerateStoreViaSetter( 1091 void NamedStoreHandlerCompiler::GenerateStoreViaSetter(
1187 MacroAssembler* masm, 1092 MacroAssembler* masm, Handle<HeapType> type, Register receiver,
1188 Handle<HeapType> type,
1189 Register receiver,
1190 Handle<JSFunction> setter) { 1093 Handle<JSFunction> setter) {
1191 // ----------- S t a t e ------------- 1094 // ----------- S t a t e -------------
1192 // -- lr : return address 1095 // -- lr : return address
1193 // ----------------------------------- 1096 // -----------------------------------
1194 { 1097 {
1195 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); 1098 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
1196 1099
1197 // Save value register, so we can restore it later. 1100 // Save value register, so we can restore it later.
1198 __ push(value()); 1101 __ push(value());
1199 1102
(...skipping 22 matching lines...) Expand all
1222 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 1125 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
1223 } 1126 }
1224 __ Ret(); 1127 __ Ret();
1225 } 1128 }
1226 1129
1227 1130
1228 #undef __ 1131 #undef __
1229 #define __ ACCESS_MASM(masm()) 1132 #define __ ACCESS_MASM(masm())
1230 1133
1231 1134
1232 Handle<Code> StoreStubCompiler::CompileStoreInterceptor( 1135 Handle<Code> NamedStoreHandlerCompiler::CompileStoreInterceptor(
1233 Handle<JSObject> object, 1136 Handle<JSObject> object, Handle<Name> name) {
1234 Handle<Name> name) {
1235 __ Push(receiver(), this->name(), value()); 1137 __ Push(receiver(), this->name(), value());
1236 1138
1237 // Do tail-call to the runtime system. 1139 // Do tail-call to the runtime system.
1238 ExternalReference store_ic_property = 1140 ExternalReference store_ic_property =
1239 ExternalReference(IC_Utility(IC::kStoreInterceptorProperty), isolate()); 1141 ExternalReference(IC_Utility(IC::kStoreInterceptorProperty), isolate());
1240 __ TailCallExternalReference(store_ic_property, 3, 1); 1142 __ TailCallExternalReference(store_ic_property, 3, 1);
1241 1143
1242 // Return the generated code. 1144 // Return the generated code.
1243 return GetCode(kind(), Code::FAST, name); 1145 return GetCode(kind(), Code::FAST, name);
1244 } 1146 }
1245 1147
1246 1148
1247 Handle<Code> LoadStubCompiler::CompileLoadNonexistent(Handle<HeapType> type, 1149 Handle<Code> NamedLoadHandlerCompiler::CompileLoadNonexistent(
1248 Handle<JSObject> last, 1150 Handle<HeapType> type, Handle<JSObject> last, Handle<Name> name) {
1249 Handle<Name> name) { 1151 NonexistentFrontend(type, last, name);
1250 NonexistentHandlerFrontend(type, last, name);
1251 1152
1252 // Return undefined if maps of the full prototype chain are still the 1153 // Return undefined if maps of the full prototype chain are still the
1253 // same and no global property with this name contains a value. 1154 // same and no global property with this name contains a value.
1254 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); 1155 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex);
1255 __ Ret(); 1156 __ Ret();
1256 1157
1257 // Return the generated code. 1158 // Return the generated code.
1258 return GetCode(kind(), Code::FAST, name); 1159 return GetCode(kind(), Code::FAST, name);
1259 } 1160 }
1260 1161
1261 1162
1262 Register* LoadStubCompiler::registers() { 1163 Register* PropertyAccessCompiler::load_calling_convention() {
1263 // receiver, name, scratch1, scratch2, scratch3, scratch4. 1164 // receiver, name, scratch1, scratch2, scratch3, scratch4.
1264 Register receiver = LoadIC::ReceiverRegister(); 1165 Register receiver = LoadIC::ReceiverRegister();
1265 Register name = LoadIC::NameRegister(); 1166 Register name = LoadIC::NameRegister();
1266 static Register registers[] = { receiver, name, r3, r0, r4, r5 }; 1167 static Register registers[] = { receiver, name, r3, r0, r4, r5 };
1267 return registers; 1168 return registers;
1268 } 1169 }
1269 1170
1270 1171
1271 Register* KeyedLoadStubCompiler::registers() { 1172 Register* PropertyAccessCompiler::store_calling_convention() {
1272 // receiver, name, scratch1, scratch2, scratch3, scratch4.
1273 Register receiver = LoadIC::ReceiverRegister();
1274 Register name = LoadIC::NameRegister();
1275 static Register registers[] = { receiver, name, r3, r0, r4, r5 };
1276 return registers;
1277 }
1278
1279
1280 Register StoreStubCompiler::value() {
1281 return StoreIC::ValueRegister();
1282 }
1283
1284
1285 Register* StoreStubCompiler::registers() {
1286 // receiver, name, scratch1, scratch2, scratch3. 1173 // receiver, name, scratch1, scratch2, scratch3.
1287 Register receiver = StoreIC::ReceiverRegister(); 1174 Register receiver = StoreIC::ReceiverRegister();
1288 Register name = StoreIC::NameRegister(); 1175 Register name = StoreIC::NameRegister();
1289 static Register registers[] = { receiver, name, r3, r4, r5 }; 1176 static Register registers[] = { receiver, name, r3, r4, r5 };
1290 return registers; 1177 return registers;
1291 } 1178 }
1292 1179
1293 1180
1294 Register* KeyedStoreStubCompiler::registers() { 1181 Register* PropertyAccessCompiler::keyed_store_calling_convention() {
1295 // receiver, name, scratch1/map, scratch2, scratch3. 1182 // receiver, name, scratch1/map, scratch2, scratch3.
1296 Register receiver = KeyedStoreIC::ReceiverRegister(); 1183 Register receiver = KeyedStoreIC::ReceiverRegister();
1297 Register name = KeyedStoreIC::NameRegister(); 1184 Register name = KeyedStoreIC::NameRegister();
1298 Register map = KeyedStoreIC::MapRegister(); 1185 Register map = KeyedStoreIC::MapRegister();
1299 static Register registers[] = { receiver, name, map, r4, r5 }; 1186 static Register registers[] = { receiver, name, map, r4, r5 };
1300 return registers; 1187 return registers;
1301 } 1188 }
1302 1189
1303 1190
1191 Register NamedStoreHandlerCompiler::value() { return StoreIC::ValueRegister(); }
1192
1193
1304 #undef __ 1194 #undef __
1305 #define __ ACCESS_MASM(masm) 1195 #define __ ACCESS_MASM(masm)
1306 1196
1307 1197
1308 void LoadStubCompiler::GenerateLoadViaGetter(MacroAssembler* masm, 1198 void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
1309 Handle<HeapType> type, 1199 MacroAssembler* masm, Handle<HeapType> type, Register receiver,
1310 Register receiver, 1200 Handle<JSFunction> getter) {
1311 Handle<JSFunction> getter) {
1312 // ----------- S t a t e ------------- 1201 // ----------- S t a t e -------------
1313 // -- r0 : receiver 1202 // -- r0 : receiver
1314 // -- r2 : name 1203 // -- r2 : name
1315 // -- lr : return address 1204 // -- lr : return address
1316 // ----------------------------------- 1205 // -----------------------------------
1317 { 1206 {
1318 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); 1207 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
1319 1208
1320 if (!getter.is_null()) { 1209 if (!getter.is_null()) {
1321 // Call the JavaScript getter with the receiver on the stack. 1210 // Call the JavaScript getter with the receiver on the stack.
(...skipping 17 matching lines...) Expand all
1339 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 1228 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
1340 } 1229 }
1341 __ Ret(); 1230 __ Ret();
1342 } 1231 }
1343 1232
1344 1233
1345 #undef __ 1234 #undef __
1346 #define __ ACCESS_MASM(masm()) 1235 #define __ ACCESS_MASM(masm())
1347 1236
1348 1237
1349 Handle<Code> LoadStubCompiler::CompileLoadGlobal( 1238 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal(
1350 Handle<HeapType> type, 1239 Handle<HeapType> type, Handle<GlobalObject> global,
1351 Handle<GlobalObject> global, 1240 Handle<PropertyCell> cell, Handle<Name> name, bool is_dont_delete) {
1352 Handle<PropertyCell> cell,
1353 Handle<Name> name,
1354 bool is_dont_delete) {
1355 Label miss; 1241 Label miss;
1356 HandlerFrontendHeader(type, receiver(), global, name, &miss); 1242 FrontendHeader(type, receiver(), global, name, &miss);
1357 1243
1358 // Get the value from the cell. 1244 // Get the value from the cell.
1359 __ mov(r3, Operand(cell)); 1245 __ mov(r3, Operand(cell));
1360 __ ldr(r4, FieldMemOperand(r3, Cell::kValueOffset)); 1246 __ ldr(r4, FieldMemOperand(r3, Cell::kValueOffset));
1361 1247
1362 // Check for deleted property if property can actually be deleted. 1248 // Check for deleted property if property can actually be deleted.
1363 if (!is_dont_delete) { 1249 if (!is_dont_delete) {
1364 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); 1250 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
1365 __ cmp(r4, ip); 1251 __ cmp(r4, ip);
1366 __ b(eq, &miss); 1252 __ b(eq, &miss);
1367 } 1253 }
1368 1254
1369 Counters* counters = isolate()->counters(); 1255 Counters* counters = isolate()->counters();
1370 __ IncrementCounter(counters->named_load_global_stub(), 1, r1, r3); 1256 __ IncrementCounter(counters->named_load_global_stub(), 1, r1, r3);
1371 __ mov(r0, r4); 1257 __ mov(r0, r4);
1372 __ Ret(); 1258 __ Ret();
1373 1259
1374 HandlerFrontendFooter(name, &miss); 1260 FrontendFooter(name, &miss);
1375 1261
1376 // Return the generated code. 1262 // Return the generated code.
1377 return GetCode(kind(), Code::NORMAL, name); 1263 return GetCode(kind(), Code::NORMAL, name);
1378 } 1264 }
1379 1265
1380 1266
1381 Handle<Code> BaseLoadStoreStubCompiler::CompilePolymorphicIC( 1267 Handle<Code> PropertyICCompiler::CompilePolymorphic(TypeHandleList* types,
1382 TypeHandleList* types, 1268 CodeHandleList* handlers,
1383 CodeHandleList* handlers, 1269 Handle<Name> name,
1384 Handle<Name> name, 1270 Code::StubType type,
1385 Code::StubType type, 1271 IcCheckType check) {
1386 IcCheckType check) {
1387 Label miss; 1272 Label miss;
1388 1273
1389 if (check == PROPERTY && 1274 if (check == PROPERTY &&
1390 (kind() == Code::KEYED_LOAD_IC || kind() == Code::KEYED_STORE_IC)) { 1275 (kind() == Code::KEYED_LOAD_IC || kind() == Code::KEYED_STORE_IC)) {
1391 __ cmp(this->name(), Operand(name)); 1276 __ cmp(this->name(), Operand(name));
1392 __ b(ne, &miss); 1277 __ b(ne, &miss);
1393 } 1278 }
1394 1279
1395 Label number_case; 1280 Label number_case;
1396 Label* smi_target = IncludesNumberType(types) ? &number_case : &miss; 1281 Label* smi_target = IncludesNumberType(types) ? &number_case : &miss;
(...skipping 22 matching lines...) Expand all
1419 } 1304 }
1420 } 1305 }
1421 ASSERT(number_of_handled_maps != 0); 1306 ASSERT(number_of_handled_maps != 0);
1422 1307
1423 __ bind(&miss); 1308 __ bind(&miss);
1424 TailCallBuiltin(masm(), MissBuiltin(kind())); 1309 TailCallBuiltin(masm(), MissBuiltin(kind()));
1425 1310
1426 // Return the generated code. 1311 // Return the generated code.
1427 InlineCacheState state = 1312 InlineCacheState state =
1428 number_of_handled_maps > 1 ? POLYMORPHIC : MONOMORPHIC; 1313 number_of_handled_maps > 1 ? POLYMORPHIC : MONOMORPHIC;
1429 return GetICCode(kind(), type, name, state); 1314 return GetCode(kind(), type, name, state);
1430 } 1315 }
1431 1316
1432 1317
1433 void StoreStubCompiler::GenerateStoreArrayLength() { 1318 void NamedStoreHandlerCompiler::GenerateStoreArrayLength() {
1434 // Prepare tail call to StoreIC_ArrayLength. 1319 // Prepare tail call to StoreIC_ArrayLength.
1435 __ Push(receiver(), value()); 1320 __ Push(receiver(), value());
1436 1321
1437 ExternalReference ref = 1322 ExternalReference ref =
1438 ExternalReference(IC_Utility(IC::kStoreIC_ArrayLength), 1323 ExternalReference(IC_Utility(IC::kStoreIC_ArrayLength),
1439 masm()->isolate()); 1324 masm()->isolate());
1440 __ TailCallExternalReference(ref, 2, 1); 1325 __ TailCallExternalReference(ref, 2, 1);
1441 } 1326 }
1442 1327
1443 1328
1444 Handle<Code> KeyedStoreStubCompiler::CompileStorePolymorphic( 1329 Handle<Code> PropertyICCompiler::CompileIndexedStorePolymorphic(
1445 MapHandleList* receiver_maps, 1330 MapHandleList* receiver_maps, CodeHandleList* handler_stubs,
1446 CodeHandleList* handler_stubs,
1447 MapHandleList* transitioned_maps) { 1331 MapHandleList* transitioned_maps) {
1448 Label miss; 1332 Label miss;
1449 __ JumpIfSmi(receiver(), &miss); 1333 __ JumpIfSmi(receiver(), &miss);
1450 1334
1451 int receiver_count = receiver_maps->length(); 1335 int receiver_count = receiver_maps->length();
1452 __ ldr(scratch1(), FieldMemOperand(receiver(), HeapObject::kMapOffset)); 1336 __ ldr(scratch1(), FieldMemOperand(receiver(), HeapObject::kMapOffset));
1453 for (int i = 0; i < receiver_count; ++i) { 1337 for (int i = 0; i < receiver_count; ++i) {
1454 __ mov(ip, Operand(receiver_maps->at(i))); 1338 __ mov(ip, Operand(receiver_maps->at(i)));
1455 __ cmp(scratch1(), ip); 1339 __ cmp(scratch1(), ip);
1456 if (transitioned_maps->at(i).is_null()) { 1340 if (transitioned_maps->at(i).is_null()) {
1457 __ Jump(handler_stubs->at(i), RelocInfo::CODE_TARGET, eq); 1341 __ Jump(handler_stubs->at(i), RelocInfo::CODE_TARGET, eq);
1458 } else { 1342 } else {
1459 Label next_map; 1343 Label next_map;
1460 __ b(ne, &next_map); 1344 __ b(ne, &next_map);
1461 __ mov(transition_map(), Operand(transitioned_maps->at(i))); 1345 __ mov(transition_map(), Operand(transitioned_maps->at(i)));
1462 __ Jump(handler_stubs->at(i), RelocInfo::CODE_TARGET, al); 1346 __ Jump(handler_stubs->at(i), RelocInfo::CODE_TARGET, al);
1463 __ bind(&next_map); 1347 __ bind(&next_map);
1464 } 1348 }
1465 } 1349 }
1466 1350
1467 __ bind(&miss); 1351 __ bind(&miss);
1468 TailCallBuiltin(masm(), MissBuiltin(kind())); 1352 TailCallBuiltin(masm(), MissBuiltin(kind()));
1469 1353
1470 // Return the generated code. 1354 // Return the generated code.
1471 return GetICCode( 1355 return GetCode(kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC);
1472 kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC);
1473 } 1356 }
1474 1357
1475 1358
1476 #undef __ 1359 #undef __
1477 #define __ ACCESS_MASM(masm) 1360 #define __ ACCESS_MASM(masm)
1478 1361
1479 1362
1480 void KeyedLoadStubCompiler::GenerateLoadDictionaryElement( 1363 void IndexedHandlerCompiler::GenerateLoadDictionaryElement(
1481 MacroAssembler* masm) { 1364 MacroAssembler* masm) {
1482 // The return address is in lr. 1365 // The return address is in lr.
1483 Label slow, miss; 1366 Label slow, miss;
1484 1367
1485 Register key = LoadIC::NameRegister(); 1368 Register key = LoadIC::NameRegister();
1486 Register receiver = LoadIC::ReceiverRegister(); 1369 Register receiver = LoadIC::ReceiverRegister();
1487 ASSERT(receiver.is(r1)); 1370 ASSERT(receiver.is(r1));
1488 ASSERT(key.is(r2)); 1371 ASSERT(key.is(r2));
1489 1372
1490 __ UntagAndJumpIfNotSmi(r6, key, &miss); 1373 __ UntagAndJumpIfNotSmi(r6, key, &miss);
(...skipping 13 matching lines...) Expand all
1504 1387
1505 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); 1388 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
1506 } 1389 }
1507 1390
1508 1391
1509 #undef __ 1392 #undef __
1510 1393
1511 } } // namespace v8::internal 1394 } } // namespace v8::internal
1512 1395
1513 #endif // V8_TARGET_ARCH_ARM 1396 #endif // V8_TARGET_ARCH_ARM
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698