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

Side by Side Diff: src/ic-arm.cc

Issue 11277: More work on completing Keyed IC code on ARM port.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 12 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | src/macro-assembler-arm.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
135 Label miss; 135 Label miss;
136 136
137 __ ldr(r0, MemOperand(sp, 0)); 137 __ ldr(r0, MemOperand(sp, 0));
138 138
139 StubCompiler::GenerateLoadArrayLength(masm, r0, r3, &miss); 139 StubCompiler::GenerateLoadArrayLength(masm, r0, r3, &miss);
140 __ bind(&miss); 140 __ bind(&miss);
141 StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC); 141 StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC);
142 } 142 }
143 143
144 144
145 // Generate code to check if an object is a string. If the object is
146 // a string, the map's instance type is left in the scratch1 register.
147 static void GenerateStringCheck(MacroAssembler* masm,
148 Register receiver,
149 Register scratch1,
150 Register scratch2,
151 Label* smi,
152 Label* non_string_object) {
153 // Check that the receiver isn't a smi.
154 __ tst(receiver, Operand(kSmiTagMask));
155 __ b(eq, smi);
156
157 // Check that the object is a string.
158 __ ldr(scratch1, FieldMemOperand(receiver, HeapObject::kMapOffset));
159 __ ldrb(scratch1, FieldMemOperand(scratch1, Map::kInstanceTypeOffset));
160 __ and_(scratch2, scratch1, Operand(kIsNotStringMask));
161 // The cast is to resolve the overload for the argument of 0x0.
162 __ cmp(scratch2, Operand(static_cast<int32_t>(kStringTag)));
163 __ b(ne, non_string_object);
164 }
165
166
167 void LoadIC::GenerateStringLength(MacroAssembler* masm) { 145 void LoadIC::GenerateStringLength(MacroAssembler* masm) {
168 // ----------- S t a t e ------------- 146 // ----------- S t a t e -------------
169 // -- r2 : name 147 // -- r2 : name
170 // -- lr : return address 148 // -- lr : return address
171 // -- [sp] : receiver 149 // -- [sp] : receiver
172 // ----------------------------------- 150 // -----------------------------------
173 Label miss, load_length, check_wrapper; 151 Label miss;
174 152
175 __ ldr(r0, MemOperand(sp, 0)); 153 __ ldr(r0, MemOperand(sp, 0));
176 154
177 // Check if the object is a string leaving the instance type in the 155 StubCompiler::GenerateLoadStringLength2(masm, r0, r1, r3, &miss);
178 // r1 register.
179 GenerateStringCheck(masm, r0, r1, r3, &miss, &check_wrapper);
180
181 // Load length directly from the string.
182 __ bind(&load_length);
183 __ and_(r1, r1, Operand(kStringSizeMask));
184 __ add(r1, r1, Operand(String::kHashShift));
185 __ ldr(r0, FieldMemOperand(r0, String::kLengthOffset));
186 __ mov(r0, Operand(r0, LSR, r1));
187 __ mov(r0, Operand(r0, LSL, kSmiTagSize));
188 __ Ret();
189
190 // Check if the object is a JSValue wrapper.
191 __ bind(&check_wrapper);
192 __ cmp(r1, Operand(JS_VALUE_TYPE));
193 __ b(ne, &miss);
194
195 // Check if the wrapped value is a string and load the length
196 // directly if it is.
197 __ ldr(r0, FieldMemOperand(r0, JSValue::kValueOffset));
198 GenerateStringCheck(masm, r0, r1, r3, &miss, &miss);
199 __ b(&load_length);
200
201 // Cache miss: Jump to runtime. 156 // Cache miss: Jump to runtime.
202 __ bind(&miss); 157 __ bind(&miss);
203 StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC); 158 StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC);
204 } 159 }
205 160
206 161
207 void LoadIC::GenerateFunctionPrototype(MacroAssembler* masm) { 162 void LoadIC::GenerateFunctionPrototype(MacroAssembler* masm) {
208 // ----------- S t a t e ------------- 163 // ----------- S t a t e -------------
209 // -- r2 : name 164 // -- r2 : name
210 // -- lr : return address 165 // -- lr : return address
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after
493 // ----------------------------------- 448 // -----------------------------------
494 449
495 __ ldr(r3, MemOperand(sp, 0)); 450 __ ldr(r3, MemOperand(sp, 0));
496 __ stm(db_w, sp, r2.bit() | r3.bit()); 451 __ stm(db_w, sp, r2.bit() | r3.bit());
497 452
498 // Perform tail call to the entry. 453 // Perform tail call to the entry.
499 __ TailCallRuntime(f, 2); 454 __ TailCallRuntime(f, 2);
500 } 455 }
501 456
502 457
503 // TODO(1224671): ICs for keyed load/store is not completed on ARM.
504 Object* KeyedLoadIC_Miss(Arguments args); 458 Object* KeyedLoadIC_Miss(Arguments args);
505 459
506 460
507 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { 461 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) {
508 Generate(masm, ExternalReference(IC_Utility(kKeyedLoadIC_Miss))); 462 Generate(masm, ExternalReference(IC_Utility(kKeyedLoadIC_Miss)));
509 } 463 }
510 464
511 465
512 void KeyedLoadIC::Generate(MacroAssembler* masm, const ExternalReference& f) { 466 void KeyedLoadIC::Generate(MacroAssembler* masm, const ExternalReference& f) {
513 // ---------- S t a t e -------------- 467 // ---------- S t a t e --------------
514 // -- lr : return address 468 // -- lr : return address
515 // -- sp[0] : key 469 // -- sp[0] : key
516 // -- sp[4] : receiver 470 // -- sp[4] : receiver
517 __ ldm(ia, sp, r2.bit() | r3.bit()); 471 __ ldm(ia, sp, r1.bit() | r3.bit());
518 __ stm(db_w, sp, r2.bit() | r3.bit()); 472 __ stm(db_w, sp, r1.bit() | r3.bit());
iposva 2008/11/20 05:17:30 Why are you using r1 and r3 here and not r0 and r1
Feng Qian 2008/11/20 16:50:38 All r0 - r3 are available. I cannot remember why I
519 473
520 __ TailCallRuntime(f, 2); 474 __ TailCallRuntime(f, 2);
521 } 475 }
522 476
523 477
524 // TODO(1224671): implement the fast case.
525 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { 478 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
526 // ---------- S t a t e -------------- 479 // ---------- S t a t e --------------
527 // -- lr : return address 480 // -- lr : return address
528 // -- sp[0] : key 481 // -- sp[0] : key
529 // -- sp[4] : receiver 482 // -- sp[4] : receiver
483 Label slow, fast;
530 484
531 KeyedLoadIC::Generate(masm, ExternalReference(Runtime::kKeyedGetProperty)); 485 // Get the key and receiver object from the stack.
486 __ ldm(ia, sp, r0.bit() | r1.bit());
487 // Check that the key is a smi.
488 __ tst(r0, Operand(kSmiTagMask));
489 __ b(ne, &slow);
490 __ mov(r0, Operand(r0, ASR, kSmiTagSize));
491 // Check that the object isn't a smi.
492 __ tst(r1, Operand(kSmiTagMask));
493 __ b(eq, &slow);
494
495 // Check that the object is some kind of JS object EXCEPT JS Value type.
496 // In the case that the object is a value-wrapper object,
497 // we enter the runtime system to make sure that indexing into string
498 // objects work as intended.
499 ASSERT(JS_OBJECT_TYPE > JS_VALUE_TYPE);
500 __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset));
501 __ ldrb(r2, FieldMemOperand(r2, Map::kInstanceTypeOffset));
502 __ cmp(r2, Operand(JS_OBJECT_TYPE));
503 __ b(lt, &slow);
504
505 // Get the elements array of the object.
506 __ ldr(r1, FieldMemOperand(r1, JSObject::kElementsOffset));
507 // Check that the object is in fast mode (not dictionary).
508 __ ldr(r3, FieldMemOperand(r1, HeapObject::kMapOffset));
509 __ cmp(r3, Operand(Factory::hash_table_map()));
510 __ b(eq, &slow);
511 // Check that the key (index) is within bounds.
512 __ ldr(r3, FieldMemOperand(r1, Array::kLengthOffset));
513 __ cmp(r0, Operand(r3));
514 __ b(lo, &fast);
515
516 // Slow case: Push extra copies of the arguments (2).
517 __ bind(&slow);
518 __ IncrementCounter(&Counters::keyed_load_generic_slow, 1, r0, r1);
519 __ ldm(ia, sp, r0.bit() | r1.bit());
520 __ stm(db_w, sp, r0.bit() | r1.bit());
521 // Do tail-call to runtime routine.
522 __ TailCallRuntime(ExternalReference(Runtime::kGetProperty), 2);
523
524 // Fast case: Do the load.
525 __ bind(&fast);
526 __ add(r3, r1, Operand(Array::kHeaderSize - kHeapObjectTag));
527 __ ldr(r0, MemOperand(r3, r0, LSL, kPointerSizeLog2));
528 __ cmp(r0, Operand(Factory::the_hole_value()));
529 // In case the loaded value is the_hole we have to consult GetProperty
530 // to ensure the prototype chain is searched.
531 __ b(eq, &slow);
532
533 __ Ret();
532 } 534 }
533 535
534 536
535 void KeyedStoreIC::Generate(MacroAssembler* masm, 537 void KeyedStoreIC::Generate(MacroAssembler* masm,
536 const ExternalReference& f) { 538 const ExternalReference& f) {
537 // ---------- S t a t e -------------- 539 // ---------- S t a t e --------------
538 // -- r0 : value 540 // -- r0 : value
539 // -- lr : return address 541 // -- lr : return address
540 // -- sp[0] : key 542 // -- sp[0] : key
541 // -- sp[1] : receiver 543 // -- sp[1] : receiver
542 544
543 __ ldm(ia, sp, r2.bit() | r3.bit()); 545 __ ldm(ia, sp, r1.bit() | r3.bit());
544 __ stm(db_w, sp, r0.bit() | r2.bit() | r3.bit()); 546 __ stm(db_w, sp, r0.bit() | r1.bit() | r3.bit());
545 547
546 __ TailCallRuntime(f, 3); 548 __ TailCallRuntime(f, 3);
547 } 549 }
548 550
549 551
550 // TODO(1224671): implement the fast case.
551 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm) { 552 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm) {
552 // ---------- S t a t e -------------- 553 // ---------- S t a t e --------------
553 // -- r0 : value 554 // -- r0 : value
554 // -- lr : return address 555 // -- lr : return address
555 // -- sp[0] : key 556 // -- sp[0] : key
556 // -- sp[1] : receiver 557 // -- sp[1] : receiver
558 Label slow, fast, array, extra, exit;
559 // Get the key and the object from the stack.
560 __ ldm(ia, sp, r1.bit() | r3.bit()); // r1 = key, r3 = receiver
561 // Check that the key is a smi.
562 __ tst(r1, Operand(kSmiTagMask));
563 __ b(ne, &slow);
564 // Check that the object isn't a smi.
565 __ tst(r3, Operand(kSmiTagMask));
566 __ b(eq, &slow);
567 // Get the type of the object from its map.
568 __ ldr(r2, FieldMemOperand(r3, HeapObject::kMapOffset));
569 __ ldrb(r2, FieldMemOperand(r2, Map::kInstanceTypeOffset));
570 // Check if the object is a JS array or not.
571 __ cmp(r2, Operand(JS_ARRAY_TYPE));
572 __ b(eq, &array);
573 // Check that the object is some kind of JS object.
574 __ cmp(r2, Operand(FIRST_JS_OBJECT_TYPE));
575 __ b(lt, &slow);
557 576
558 KeyedStoreIC::Generate(masm, ExternalReference(Runtime::kSetProperty)); 577
578 // Object case: Check key against length in the elements array.
579 __ ldr(r3, FieldMemOperand(r3, JSObject::kElementsOffset));
580 // Check that the object is in fast mode (not dictionary).
581 __ ldr(r2, FieldMemOperand(r3, HeapObject::kMapOffset));
582 __ cmp(r2, Operand(Factory::hash_table_map()));
583 __ b(eq, &slow);
584 // Untag the key (for checking against untagged length in the fixed array).
585 __ mov(r1, Operand(r1, ASR, kSmiTagSize));
586 // Compute address to store into and check array bounds.
587 __ add(r2, r3, Operand(Array::kHeaderSize - kHeapObjectTag));
588 __ add(r2, r2, Operand(r1, LSL, kPointerSizeLog2));
589 __ ldr(ip, FieldMemOperand(r3, Array::kLengthOffset));
590 __ cmp(r1, Operand(ip));
591 __ b(lo, &fast);
592
593
594 // Slow case: Push extra copies of the arguments (3).
595 __ bind(&slow);
596 __ ldm(ia, sp, r1.bit() | r3.bit()); // r0 == value, r1 == key, r3 == object
597 __ stm(db_w, sp, r0.bit() | r1.bit() | r3.bit());
598 // Do tail-call to runtime routine.
599 __ TailCallRuntime(ExternalReference(Runtime::kSetProperty), 3);
600
601 // Extra capacity case: Check if there is extra capacity to
602 // perform the store and update the length. Used for adding one
603 // element to the array by writing to array[array.length].
604 // r0 == value, r1 == key, r2 == elements, r3 == object
605 __ bind(&extra);
606 __ b(ne, &slow); // do not leave holes in the array
607 __ mov(r1, Operand(r1, ASR, kSmiTagSize)); // untag
608 __ ldr(ip, FieldMemOperand(r2, Array::kLengthOffset));
609 __ cmp(r1, Operand(ip));
610 __ b(hs, &slow);
611 __ mov(r1, Operand(r1, LSL, kSmiTagSize)); // restore tag
612 __ add(r1, r1, Operand(1 << kSmiTagSize)); // and increment
613 __ str(r1, FieldMemOperand(r3, JSArray::kLengthOffset));
614 __ mov(r3, Operand(r2));
615 // NOTE: Computing the address to store into must take the fact
616 // that the key has been incremented into account.
617 int displacement = Array::kHeaderSize - kHeapObjectTag -
618 ((1 << kSmiTagSize) * 2);
619 __ add(r2, r2, Operand(displacement));
620 __ add(r2, r2, Operand(r1, LSL, kPointerSizeLog2 - kSmiTagSize));
621 __ b(&fast);
622
623
624 // Array case: Get the length and the elements array from the JS
625 // array. Check that the array is in fast mode; if it is the
626 // length is always a smi.
627 // r0 == value, r3 == object
628 __ bind(&array);
629 __ ldr(r2, FieldMemOperand(r3, JSObject::kElementsOffset));
630 __ ldr(r1, FieldMemOperand(r2, HeapObject::kMapOffset));
631 __ cmp(r1, Operand(Factory::hash_table_map()));
632 __ b(eq, &slow);
633
634 // Check the key against the length in the array, compute the
635 // address to store into and fall through to fast case.
636 __ ldr(r1, MemOperand(sp));
iposva 2008/11/20 05:17:30 Can you use a different register as temporary regi
Feng Qian 2008/11/20 16:50:38 Done.
637 // r0 == value, r1 == key, r2 == elements, r3 == object.
638 __ ldr(ip, FieldMemOperand(r3, JSArray::kLengthOffset));
639 __ cmp(r1, Operand(ip));
640 __ b(hs, &extra);
641 __ mov(r3, Operand(r2));
642 __ add(r2, r2, Operand(Array::kHeaderSize - kHeapObjectTag));
643 __ add(r2, r2, Operand(r1, LSL, kPointerSizeLog2 - kSmiTagSize));
644
645
646 // Fast case: Do the store.
647 // r0 == value, r2 == address to store into, r3 == elements
648 __ bind(&fast);
649 __ str(r0, MemOperand(r2));
650 // Skip write barrier if the written value is a smi.
651 __ tst(r0, Operand(kSmiTagMask));
652 __ b(eq, &exit);
653 // Update write barrier for the elements array address.
654 __ sub(r1, r2, Operand(r3));
655 __ RecordWrite(r3, r1, r2);
656
657 __ bind(&exit);
658 __ Ret();
559 } 659 }
560 660
561 661
562 void KeyedStoreIC::GenerateExtendStorage(MacroAssembler* masm) { 662 void KeyedStoreIC::GenerateExtendStorage(MacroAssembler* masm) {
563 // ---------- S t a t e -------------- 663 // ---------- S t a t e --------------
564 // -- r0 : value 664 // -- r0 : value
565 // -- lr : return address 665 // -- lr : return address
566 // -- sp[0] : key 666 // -- sp[0] : key
567 // -- sp[1] : receiver 667 // -- sp[1] : receiver
568 // ----------- S t a t e ------------- 668 // ----------- S t a t e -------------
569 669
570 __ ldm(ia, sp, r2.bit() | r3.bit()); 670 __ ldm(ia, sp, r1.bit() | r3.bit());
571 __ stm(db_w, sp, r0.bit() | r2.bit() | r3.bit()); 671 __ stm(db_w, sp, r0.bit() | r1.bit() | r3.bit());
572 672
573 // Perform tail call to the entry. 673 // Perform tail call to the entry.
574 __ TailCallRuntime( 674 __ TailCallRuntime(
575 ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3); 675 ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3);
576 } 676 }
577 677
578 678
579 void StoreIC::GenerateMegamorphic(MacroAssembler* masm) { 679 void StoreIC::GenerateMegamorphic(MacroAssembler* masm) {
580 // ----------- S t a t e ------------- 680 // ----------- S t a t e -------------
581 // -- r0 : value 681 // -- r0 : value
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
624 724
625 // Perform tail call to the entry. 725 // Perform tail call to the entry.
626 __ TailCallRuntime(f, 3); 726 __ TailCallRuntime(f, 3);
627 } 727 }
628 728
629 729
630 #undef __ 730 #undef __
631 731
632 732
633 } } // namespace v8::internal 733 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | src/macro-assembler-arm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698