| OLD | NEW | 
|---|
| 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 69 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 80   // Possible work-around for http://crbug.com/16276. | 80   // Possible work-around for http://crbug.com/16276. | 
| 81   // See also: http://codereview.chromium.org/155418. | 81   // See also: http://codereview.chromium.org/155418. | 
| 82   __ cmp(r3, Operand(JS_GLOBAL_OBJECT_TYPE)); | 82   __ cmp(r3, Operand(JS_GLOBAL_OBJECT_TYPE)); | 
| 83   __ b(eq, miss); | 83   __ b(eq, miss); | 
| 84   __ cmp(r3, Operand(JS_BUILTINS_OBJECT_TYPE)); | 84   __ cmp(r3, Operand(JS_BUILTINS_OBJECT_TYPE)); | 
| 85   __ b(eq, miss); | 85   __ b(eq, miss); | 
| 86 | 86 | 
| 87   // Check that the properties array is a dictionary. | 87   // Check that the properties array is a dictionary. | 
| 88   __ ldr(t0, FieldMemOperand(t1, JSObject::kPropertiesOffset)); | 88   __ ldr(t0, FieldMemOperand(t1, JSObject::kPropertiesOffset)); | 
| 89   __ ldr(r3, FieldMemOperand(t0, HeapObject::kMapOffset)); | 89   __ ldr(r3, FieldMemOperand(t0, HeapObject::kMapOffset)); | 
| 90   __ cmp(r3, Operand(Factory::hash_table_map())); | 90   __ LoadRoot(ip, Heap::kHashTableMapRootIndex); | 
|  | 91   __ cmp(r3, ip); | 
| 91   __ b(ne, miss); | 92   __ b(ne, miss); | 
| 92 | 93 | 
| 93   // Compute the capacity mask. | 94   // Compute the capacity mask. | 
| 94   const int kCapacityOffset = StringDictionary::kHeaderSize + | 95   const int kCapacityOffset = StringDictionary::kHeaderSize + | 
| 95       StringDictionary::kCapacityIndex * kPointerSize; | 96       StringDictionary::kCapacityIndex * kPointerSize; | 
| 96   __ ldr(r3, FieldMemOperand(t0, kCapacityOffset)); | 97   __ ldr(r3, FieldMemOperand(t0, kCapacityOffset)); | 
| 97   __ mov(r3, Operand(r3, ASR, kSmiTagSize));  // convert smi to int | 98   __ mov(r3, Operand(r3, ASR, kSmiTagSize));  // convert smi to int | 
| 98   __ sub(r3, r3, Operand(1)); | 99   __ sub(r3, r3, Operand(1)); | 
| 99 | 100 | 
| 100   const int kElementsStartOffset = StringDictionary::kHeaderSize + | 101   const int kElementsStartOffset = StringDictionary::kHeaderSize + | 
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 247   // Check for string. | 248   // Check for string. | 
| 248   __ bind(&non_number); | 249   __ bind(&non_number); | 
| 249   __ cmp(r3, Operand(FIRST_NONSTRING_TYPE)); | 250   __ cmp(r3, Operand(FIRST_NONSTRING_TYPE)); | 
| 250   __ b(hs, &non_string); | 251   __ b(hs, &non_string); | 
| 251   StubCompiler::GenerateLoadGlobalFunctionPrototype( | 252   StubCompiler::GenerateLoadGlobalFunctionPrototype( | 
| 252       masm, Context::STRING_FUNCTION_INDEX, r1); | 253       masm, Context::STRING_FUNCTION_INDEX, r1); | 
| 253   __ b(&probe); | 254   __ b(&probe); | 
| 254 | 255 | 
| 255   // Check for boolean. | 256   // Check for boolean. | 
| 256   __ bind(&non_string); | 257   __ bind(&non_string); | 
| 257   __ cmp(r1, Operand(Factory::true_value())); | 258   __ LoadRoot(ip, Heap::kTrueValueRootIndex); | 
|  | 259   __ cmp(r1, ip); | 
| 258   __ b(eq, &boolean); | 260   __ b(eq, &boolean); | 
| 259   __ cmp(r1, Operand(Factory::false_value())); | 261   __ LoadRoot(ip, Heap::kFalseValueRootIndex); | 
|  | 262   __ cmp(r1, ip); | 
| 260   __ b(ne, &miss); | 263   __ b(ne, &miss); | 
| 261   __ bind(&boolean); | 264   __ bind(&boolean); | 
| 262   StubCompiler::GenerateLoadGlobalFunctionPrototype( | 265   StubCompiler::GenerateLoadGlobalFunctionPrototype( | 
| 263       masm, Context::BOOLEAN_FUNCTION_INDEX, r1); | 266       masm, Context::BOOLEAN_FUNCTION_INDEX, r1); | 
| 264 | 267 | 
| 265   // Probe the stub cache for the value object. | 268   // Probe the stub cache for the value object. | 
| 266   __ bind(&probe); | 269   __ bind(&probe); | 
| 267   StubCache::GenerateProbe(masm, flags, r1, r2, r3, no_reg); | 270   StubCache::GenerateProbe(masm, flags, r1, r2, r3, no_reg); | 
| 268 | 271 | 
| 269   // Cache miss: Jump to runtime. | 272   // Cache miss: Jump to runtime. | 
| (...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 575   // objects work as intended. | 578   // objects work as intended. | 
| 576   ASSERT(JS_OBJECT_TYPE > JS_VALUE_TYPE); | 579   ASSERT(JS_OBJECT_TYPE > JS_VALUE_TYPE); | 
| 577   __ ldrb(r2, FieldMemOperand(r2, Map::kInstanceTypeOffset)); | 580   __ ldrb(r2, FieldMemOperand(r2, Map::kInstanceTypeOffset)); | 
| 578   __ cmp(r2, Operand(JS_OBJECT_TYPE)); | 581   __ cmp(r2, Operand(JS_OBJECT_TYPE)); | 
| 579   __ b(lt, &slow); | 582   __ b(lt, &slow); | 
| 580 | 583 | 
| 581   // Get the elements array of the object. | 584   // Get the elements array of the object. | 
| 582   __ ldr(r1, FieldMemOperand(r1, JSObject::kElementsOffset)); | 585   __ ldr(r1, FieldMemOperand(r1, JSObject::kElementsOffset)); | 
| 583   // Check that the object is in fast mode (not dictionary). | 586   // Check that the object is in fast mode (not dictionary). | 
| 584   __ ldr(r3, FieldMemOperand(r1, HeapObject::kMapOffset)); | 587   __ ldr(r3, FieldMemOperand(r1, HeapObject::kMapOffset)); | 
| 585   __ cmp(r3, Operand(Factory::fixed_array_map())); | 588   __ LoadRoot(ip, Heap::kFixedArrayMapRootIndex); | 
|  | 589   __ cmp(r3, ip); | 
| 586   __ b(ne, &slow); | 590   __ b(ne, &slow); | 
| 587   // Check that the key (index) is within bounds. | 591   // Check that the key (index) is within bounds. | 
| 588   __ ldr(r3, FieldMemOperand(r1, Array::kLengthOffset)); | 592   __ ldr(r3, FieldMemOperand(r1, Array::kLengthOffset)); | 
| 589   __ cmp(r0, Operand(r3)); | 593   __ cmp(r0, Operand(r3)); | 
| 590   __ b(lo, &fast); | 594   __ b(lo, &fast); | 
| 591 | 595 | 
| 592   // Slow case: Push extra copies of the arguments (2). | 596   // Slow case: Push extra copies of the arguments (2). | 
| 593   __ bind(&slow); | 597   __ bind(&slow); | 
| 594   __ IncrementCounter(&Counters::keyed_load_generic_slow, 1, r0, r1); | 598   __ IncrementCounter(&Counters::keyed_load_generic_slow, 1, r0, r1); | 
| 595   __ ldm(ia, sp, r0.bit() | r1.bit()); | 599   __ ldm(ia, sp, r0.bit() | r1.bit()); | 
| 596   __ stm(db_w, sp, r0.bit() | r1.bit()); | 600   __ stm(db_w, sp, r0.bit() | r1.bit()); | 
| 597   // Do tail-call to runtime routine. | 601   // Do tail-call to runtime routine. | 
| 598   __ TailCallRuntime(ExternalReference(Runtime::kGetProperty), 2); | 602   __ TailCallRuntime(ExternalReference(Runtime::kGetProperty), 2); | 
| 599 | 603 | 
| 600   // Fast case: Do the load. | 604   // Fast case: Do the load. | 
| 601   __ bind(&fast); | 605   __ bind(&fast); | 
| 602   __ add(r3, r1, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); | 606   __ add(r3, r1, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); | 
| 603   __ ldr(r0, MemOperand(r3, r0, LSL, kPointerSizeLog2)); | 607   __ ldr(r0, MemOperand(r3, r0, LSL, kPointerSizeLog2)); | 
| 604   __ cmp(r0, Operand(Factory::the_hole_value())); | 608   __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); | 
|  | 609   __ cmp(r0, ip); | 
| 605   // In case the loaded value is the_hole we have to consult GetProperty | 610   // In case the loaded value is the_hole we have to consult GetProperty | 
| 606   // to ensure the prototype chain is searched. | 611   // to ensure the prototype chain is searched. | 
| 607   __ b(eq, &slow); | 612   __ b(eq, &slow); | 
| 608 | 613 | 
| 609   __ Ret(); | 614   __ Ret(); | 
| 610 } | 615 } | 
| 611 | 616 | 
| 612 | 617 | 
| 613 void KeyedStoreIC::Generate(MacroAssembler* masm, | 618 void KeyedStoreIC::Generate(MacroAssembler* masm, | 
| 614                             const ExternalReference& f) { | 619                             const ExternalReference& f) { | 
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 654   __ b(eq, &array); | 659   __ b(eq, &array); | 
| 655   // Check that the object is some kind of JS object. | 660   // Check that the object is some kind of JS object. | 
| 656   __ cmp(r2, Operand(FIRST_JS_OBJECT_TYPE)); | 661   __ cmp(r2, Operand(FIRST_JS_OBJECT_TYPE)); | 
| 657   __ b(lt, &slow); | 662   __ b(lt, &slow); | 
| 658 | 663 | 
| 659 | 664 | 
| 660   // Object case: Check key against length in the elements array. | 665   // Object case: Check key against length in the elements array. | 
| 661   __ ldr(r3, FieldMemOperand(r3, JSObject::kElementsOffset)); | 666   __ ldr(r3, FieldMemOperand(r3, JSObject::kElementsOffset)); | 
| 662   // Check that the object is in fast mode (not dictionary). | 667   // Check that the object is in fast mode (not dictionary). | 
| 663   __ ldr(r2, FieldMemOperand(r3, HeapObject::kMapOffset)); | 668   __ ldr(r2, FieldMemOperand(r3, HeapObject::kMapOffset)); | 
| 664   __ cmp(r2, Operand(Factory::fixed_array_map())); | 669   __ LoadRoot(ip, Heap::kFixedArrayMapRootIndex); | 
|  | 670   __ cmp(r2, ip); | 
| 665   __ b(ne, &slow); | 671   __ b(ne, &slow); | 
| 666   // Untag the key (for checking against untagged length in the fixed array). | 672   // Untag the key (for checking against untagged length in the fixed array). | 
| 667   __ mov(r1, Operand(r1, ASR, kSmiTagSize)); | 673   __ mov(r1, Operand(r1, ASR, kSmiTagSize)); | 
| 668   // Compute address to store into and check array bounds. | 674   // Compute address to store into and check array bounds. | 
| 669   __ add(r2, r3, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); | 675   __ add(r2, r3, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); | 
| 670   __ add(r2, r2, Operand(r1, LSL, kPointerSizeLog2)); | 676   __ add(r2, r2, Operand(r1, LSL, kPointerSizeLog2)); | 
| 671   __ ldr(ip, FieldMemOperand(r3, FixedArray::kLengthOffset)); | 677   __ ldr(ip, FieldMemOperand(r3, FixedArray::kLengthOffset)); | 
| 672   __ cmp(r1, Operand(ip)); | 678   __ cmp(r1, Operand(ip)); | 
| 673   __ b(lo, &fast); | 679   __ b(lo, &fast); | 
| 674 | 680 | 
| (...skipping 28 matching lines...) Expand all  Loading... | 
| 703   __ b(&fast); | 709   __ b(&fast); | 
| 704 | 710 | 
| 705 | 711 | 
| 706   // Array case: Get the length and the elements array from the JS | 712   // Array case: Get the length and the elements array from the JS | 
| 707   // array. Check that the array is in fast mode; if it is the | 713   // array. Check that the array is in fast mode; if it is the | 
| 708   // length is always a smi. | 714   // length is always a smi. | 
| 709   // r0 == value, r3 == object | 715   // r0 == value, r3 == object | 
| 710   __ bind(&array); | 716   __ bind(&array); | 
| 711   __ ldr(r2, FieldMemOperand(r3, JSObject::kElementsOffset)); | 717   __ ldr(r2, FieldMemOperand(r3, JSObject::kElementsOffset)); | 
| 712   __ ldr(r1, FieldMemOperand(r2, HeapObject::kMapOffset)); | 718   __ ldr(r1, FieldMemOperand(r2, HeapObject::kMapOffset)); | 
| 713   __ cmp(r1, Operand(Factory::fixed_array_map())); | 719   __ LoadRoot(ip, Heap::kFixedArrayMapRootIndex); | 
|  | 720   __ cmp(r1, ip); | 
| 714   __ b(ne, &slow); | 721   __ b(ne, &slow); | 
| 715 | 722 | 
| 716   // Check the key against the length in the array, compute the | 723   // Check the key against the length in the array, compute the | 
| 717   // address to store into and fall through to fast case. | 724   // address to store into and fall through to fast case. | 
| 718   __ ldr(r1, MemOperand(sp));  // restore key | 725   __ ldr(r1, MemOperand(sp));  // restore key | 
| 719   // r0 == value, r1 == key, r2 == elements, r3 == object. | 726   // r0 == value, r1 == key, r2 == elements, r3 == object. | 
| 720   __ ldr(ip, FieldMemOperand(r3, JSArray::kLengthOffset)); | 727   __ ldr(ip, FieldMemOperand(r3, JSArray::kLengthOffset)); | 
| 721   __ cmp(r1, Operand(ip)); | 728   __ cmp(r1, Operand(ip)); | 
| 722   __ b(hs, &extra); | 729   __ b(hs, &extra); | 
| 723   __ mov(r3, Operand(r2)); | 730   __ mov(r3, Operand(r2)); | 
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 808 | 815 | 
| 809   // Perform tail call to the entry. | 816   // Perform tail call to the entry. | 
| 810   __ TailCallRuntime(f, 3); | 817   __ TailCallRuntime(f, 3); | 
| 811 } | 818 } | 
| 812 | 819 | 
| 813 | 820 | 
| 814 #undef __ | 821 #undef __ | 
| 815 | 822 | 
| 816 | 823 | 
| 817 } }  // namespace v8::internal | 824 } }  // namespace v8::internal | 
| OLD | NEW | 
|---|