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

Side by Side Diff: src/arm/code-stubs-arm.cc

Issue 15085026: ARM: Smi refactoring and improvements. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 7 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 // 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 303 matching lines...) Expand 10 before | Expand all | Expand 10 after
314 314
315 // Iterate through the rest of map backwards. r4 holds an index as a Smi. 315 // Iterate through the rest of map backwards. r4 holds an index as a Smi.
316 Label loop; 316 Label loop;
317 __ ldr(r4, FieldMemOperand(r1, FixedArray::kLengthOffset)); 317 __ ldr(r4, FieldMemOperand(r1, FixedArray::kLengthOffset));
318 __ bind(&loop); 318 __ bind(&loop);
319 // Do not double check first entry. 319 // Do not double check first entry.
320 __ cmp(r4, Operand(Smi::FromInt(SharedFunctionInfo::kSecondEntryIndex))); 320 __ cmp(r4, Operand(Smi::FromInt(SharedFunctionInfo::kSecondEntryIndex)));
321 __ b(eq, &install_unoptimized); 321 __ b(eq, &install_unoptimized);
322 __ sub(r4, r4, Operand(Smi::FromInt(SharedFunctionInfo::kEntryLength))); 322 __ sub(r4, r4, Operand(Smi::FromInt(SharedFunctionInfo::kEntryLength)));
323 __ add(r5, r1, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); 323 __ add(r5, r1, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
324 __ add(r5, r5, Operand(r4, LSL, kPointerSizeLog2 - kSmiTagSize)); 324 __ add(r5, r5, Operand::PointerOffsetFromSmiKey(r4));
325 __ ldr(r5, MemOperand(r5)); 325 __ ldr(r5, MemOperand(r5));
326 __ cmp(r2, r5); 326 __ cmp(r2, r5);
327 __ b(ne, &loop); 327 __ b(ne, &loop);
328 // Hit: fetch the optimized code. 328 // Hit: fetch the optimized code.
329 __ add(r5, r1, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); 329 __ add(r5, r1, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
330 __ add(r5, r5, Operand(r4, LSL, kPointerSizeLog2 - kSmiTagSize)); 330 __ add(r5, r5, Operand::PointerOffsetFromSmiKey(r4));
331 __ add(r5, r5, Operand(kPointerSize)); 331 __ add(r5, r5, Operand(kPointerSize));
332 __ ldr(r4, MemOperand(r5)); 332 __ ldr(r4, MemOperand(r5));
333 333
334 __ bind(&install_optimized); 334 __ bind(&install_optimized);
335 __ IncrementCounter(counters->fast_new_closure_install_optimized(), 335 __ IncrementCounter(counters->fast_new_closure_install_optimized(),
336 1, r6, r7); 336 1, r6, r7);
337 337
338 // TODO(fschneider): Idea: store proper code pointers in the map and either 338 // TODO(fschneider): Idea: store proper code pointers in the map and either
339 // unmangle them on marking or do nothing as the whole map is discarded on 339 // unmangle them on marking or do nothing as the whole map is discarded on
340 // major GC anyway. 340 // major GC anyway.
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
512 512
513 void Generate(MacroAssembler* masm); 513 void Generate(MacroAssembler* masm);
514 }; 514 };
515 515
516 516
517 void ConvertToDoubleStub::Generate(MacroAssembler* masm) { 517 void ConvertToDoubleStub::Generate(MacroAssembler* masm) {
518 Register exponent = result1_; 518 Register exponent = result1_;
519 Register mantissa = result2_; 519 Register mantissa = result2_;
520 520
521 Label not_special; 521 Label not_special;
522 // Convert from Smi to integer. 522 __ SmiUntag(source_);
523 __ mov(source_, Operand(source_, ASR, kSmiTagSize));
524 // Move sign bit from source to destination. This works because the sign bit 523 // Move sign bit from source to destination. This works because the sign bit
525 // in the exponent word of the double has the same position and polarity as 524 // in the exponent word of the double has the same position and polarity as
526 // the 2's complement sign bit in a Smi. 525 // the 2's complement sign bit in a Smi.
527 STATIC_ASSERT(HeapNumber::kSignMask == 0x80000000u); 526 STATIC_ASSERT(HeapNumber::kSignMask == 0x80000000u);
528 __ and_(exponent, source_, Operand(HeapNumber::kSignMask), SetCC); 527 __ and_(exponent, source_, Operand(HeapNumber::kSignMask), SetCC);
529 // Subtract from 0 if source was negative. 528 // Subtract from 0 if source was negative.
530 __ rsb(source_, source_, Operand::Zero(), LeaveCC, ne); 529 __ rsb(source_, source_, Operand::Zero(), LeaveCC, ne);
531 530
532 // We have -1, 0 or 1, which we treat specially. Register source_ contains 531 // We have -1, 0 or 1, which we treat specially. Register source_ contains
533 // absolute value: it is either equal to 1 (special case of -1 and 1), 532 // absolute value: it is either equal to 1 (special case of -1 and 1),
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
763 } 762 }
764 __ Ret(ne); 763 __ Ret(ne);
765 } else { 764 } else {
766 // Smi compared non-strictly with a non-Smi non-heap-number. Call 765 // Smi compared non-strictly with a non-Smi non-heap-number. Call
767 // the runtime. 766 // the runtime.
768 __ b(ne, slow); 767 __ b(ne, slow);
769 } 768 }
770 769
771 // Lhs is a smi, rhs is a number. 770 // Lhs is a smi, rhs is a number.
772 // Convert lhs to a double in d7. 771 // Convert lhs to a double in d7.
773 __ SmiToDoubleVFPRegister(lhs, d7, r7, s15); 772 __ SmiToDouble(d7, lhs);
774 // Load the double from rhs, tagged HeapNumber r0, to d6. 773 // Load the double from rhs, tagged HeapNumber r0, to d6.
775 __ sub(r7, rhs, Operand(kHeapObjectTag)); 774 __ sub(r7, rhs, Operand(kHeapObjectTag));
776 __ vldr(d6, r7, HeapNumber::kValueOffset); 775 __ vldr(d6, r7, HeapNumber::kValueOffset);
777 776
778 // We now have both loaded as doubles but we can skip the lhs nan check 777 // We now have both loaded as doubles but we can skip the lhs nan check
779 // since it's a smi. 778 // since it's a smi.
780 __ jmp(lhs_not_nan); 779 __ jmp(lhs_not_nan);
781 780
782 __ bind(&rhs_is_smi); 781 __ bind(&rhs_is_smi);
783 // Rhs is a smi. Check whether the non-smi lhs is a heap number. 782 // Rhs is a smi. Check whether the non-smi lhs is a heap number.
(...skipping 10 matching lines...) Expand all
794 // Smi compared non-strictly with a non-smi non-heap-number. Call 793 // Smi compared non-strictly with a non-smi non-heap-number. Call
795 // the runtime. 794 // the runtime.
796 __ b(ne, slow); 795 __ b(ne, slow);
797 } 796 }
798 797
799 // Rhs is a smi, lhs is a heap number. 798 // Rhs is a smi, lhs is a heap number.
800 // Load the double from lhs, tagged HeapNumber r1, to d7. 799 // Load the double from lhs, tagged HeapNumber r1, to d7.
801 __ sub(r7, lhs, Operand(kHeapObjectTag)); 800 __ sub(r7, lhs, Operand(kHeapObjectTag));
802 __ vldr(d7, r7, HeapNumber::kValueOffset); 801 __ vldr(d7, r7, HeapNumber::kValueOffset);
803 // Convert rhs to a double in d6 . 802 // Convert rhs to a double in d6 .
804 __ SmiToDoubleVFPRegister(rhs, d6, r7, s13); 803 __ SmiToDouble(d6, rhs);
805 // Fall through to both_loaded_as_doubles. 804 // Fall through to both_loaded_as_doubles.
806 } 805 }
807 806
808 807
809 // See comment at call site. 808 // See comment at call site.
810 static void EmitStrictTwoHeapObjectCompare(MacroAssembler* masm, 809 static void EmitStrictTwoHeapObjectCompare(MacroAssembler* masm,
811 Register lhs, 810 Register lhs,
812 Register rhs) { 811 Register rhs) {
813 ASSERT((lhs.is(r0) && rhs.is(r1)) || 812 ASSERT((lhs.is(r0) && rhs.is(r1)) ||
814 (lhs.is(r1) && rhs.is(r0))); 813 (lhs.is(r1) && rhs.is(r0)));
(...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after
1221 1220
1222 // Boolean -> its value. 1221 // Boolean -> its value.
1223 CheckOddball(masm, BOOLEAN, Heap::kFalseValueRootIndex, false); 1222 CheckOddball(masm, BOOLEAN, Heap::kFalseValueRootIndex, false);
1224 CheckOddball(masm, BOOLEAN, Heap::kTrueValueRootIndex, true); 1223 CheckOddball(masm, BOOLEAN, Heap::kTrueValueRootIndex, true);
1225 1224
1226 // 'null' -> false. 1225 // 'null' -> false.
1227 CheckOddball(masm, NULL_TYPE, Heap::kNullValueRootIndex, false); 1226 CheckOddball(masm, NULL_TYPE, Heap::kNullValueRootIndex, false);
1228 1227
1229 if (types_.Contains(SMI)) { 1228 if (types_.Contains(SMI)) {
1230 // Smis: 0 -> false, all other -> true 1229 // Smis: 0 -> false, all other -> true
1231 __ tst(tos_, Operand(kSmiTagMask)); 1230 __ SmiTst(tos_);
1232 // tos_ contains the correct return value already 1231 // tos_ contains the correct return value already
1233 __ Ret(eq); 1232 __ Ret(eq);
1234 } else if (types_.NeedsMap()) { 1233 } else if (types_.NeedsMap()) {
1235 // If we need a map later and have a Smi -> patch. 1234 // If we need a map later and have a Smi -> patch.
1236 __ JumpIfSmi(tos_, &patch); 1235 __ JumpIfSmi(tos_, &patch);
1237 } 1236 }
1238 1237
1239 if (types_.NeedsMap()) { 1238 if (types_.NeedsMap()) {
1240 __ ldr(map, FieldMemOperand(tos_, HeapObject::kMapOffset)); 1239 __ ldr(map, FieldMemOperand(tos_, HeapObject::kMapOffset));
1241 1240
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after
1526 __ vldr(d0, FieldMemOperand(r0, HeapNumber::kValueOffset)); 1525 __ vldr(d0, FieldMemOperand(r0, HeapNumber::kValueOffset));
1527 __ ECMAToInt32(r1, d0, r2, r3, r4, d1); 1526 __ ECMAToInt32(r1, d0, r2, r3, r4, d1);
1528 1527
1529 // Do the bitwise operation and check if the result fits in a smi. 1528 // Do the bitwise operation and check if the result fits in a smi.
1530 Label try_float; 1529 Label try_float;
1531 __ mvn(r1, Operand(r1)); 1530 __ mvn(r1, Operand(r1));
1532 __ cmn(r1, Operand(0x40000000)); 1531 __ cmn(r1, Operand(0x40000000));
1533 __ b(mi, &try_float); 1532 __ b(mi, &try_float);
1534 1533
1535 // Tag the result as a smi and we're done. 1534 // Tag the result as a smi and we're done.
1536 __ mov(r0, Operand(r1, LSL, kSmiTagSize)); 1535 __ SmiTag(r0, r1);
1537 __ Ret(); 1536 __ Ret();
1538 1537
1539 // Try to store the result in a heap number. 1538 // Try to store the result in a heap number.
1540 __ bind(&try_float); 1539 __ bind(&try_float);
1541 if (mode_ == UNARY_NO_OVERWRITE) { 1540 if (mode_ == UNARY_NO_OVERWRITE) {
1542 Label slow_allocate_heapnumber, heapnumber_allocated; 1541 Label slow_allocate_heapnumber, heapnumber_allocated;
1543 __ AllocateHeapNumber(r0, r3, r4, r6, &slow_allocate_heapnumber); 1542 __ AllocateHeapNumber(r0, r3, r4, r6, &slow_allocate_heapnumber);
1544 __ jmp(&heapnumber_allocated); 1543 __ jmp(&heapnumber_allocated);
1545 1544
1546 __ bind(&slow_allocate_heapnumber); 1545 __ bind(&slow_allocate_heapnumber);
(...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after
1873 // Smi tag result. 1872 // Smi tag result.
1874 __ SmiTag(right, scratch1); 1873 __ SmiTag(right, scratch1);
1875 __ Ret(); 1874 __ Ret();
1876 break; 1875 break;
1877 case Token::SHL: 1876 case Token::SHL:
1878 // Remove tags from operands. 1877 // Remove tags from operands.
1879 __ SmiUntag(scratch1, left); 1878 __ SmiUntag(scratch1, left);
1880 __ GetLeastBitsFromSmi(scratch2, right, 5); 1879 __ GetLeastBitsFromSmi(scratch2, right, 5);
1881 __ mov(scratch1, Operand(scratch1, LSL, scratch2)); 1880 __ mov(scratch1, Operand(scratch1, LSL, scratch2));
1882 // Check that the signed result fits in a Smi. 1881 // Check that the signed result fits in a Smi.
1883 __ add(scratch2, scratch1, Operand(0x40000000), SetCC); 1882 __ TrySmiTag(right, scratch1, &not_smi_result);
1884 __ b(mi, &not_smi_result);
1885 __ SmiTag(right, scratch1);
1886 __ Ret(); 1883 __ Ret();
1887 break; 1884 break;
1888 default: 1885 default:
1889 UNREACHABLE(); 1886 UNREACHABLE();
1890 } 1887 }
1891 __ bind(&not_smi_result); 1888 __ bind(&not_smi_result);
1892 } 1889 }
1893 1890
1894 1891
1895 void BinaryOpStub_GenerateHeapResultAllocation(MacroAssembler* masm, 1892 void BinaryOpStub_GenerateHeapResultAllocation(MacroAssembler* masm,
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1937 case Token::MUL: 1934 case Token::MUL:
1938 case Token::DIV: 1935 case Token::DIV:
1939 case Token::MOD: { 1936 case Token::MOD: {
1940 // Allocate new heap number for result. 1937 // Allocate new heap number for result.
1941 Register result = r5; 1938 Register result = r5;
1942 BinaryOpStub_GenerateHeapResultAllocation( 1939 BinaryOpStub_GenerateHeapResultAllocation(
1943 masm, result, heap_number_map, scratch1, scratch2, gc_required, mode); 1940 masm, result, heap_number_map, scratch1, scratch2, gc_required, mode);
1944 1941
1945 // Load left and right operands into d0 and d1. 1942 // Load left and right operands into d0 and d1.
1946 if (smi_operands) { 1943 if (smi_operands) {
1947 __ SmiUntag(scratch1, right); 1944 __ SmiToDouble(d1, right);
1948 __ vmov(d1.high(), scratch1); 1945 __ SmiToDouble(d0, left);
1949 __ vcvt_f64_s32(d1, d1.high());
1950 __ SmiUntag(scratch1, left);
1951 __ vmov(d0.high(), scratch1);
1952 __ vcvt_f64_s32(d0, d0.high());
1953 } else { 1946 } else {
1954 // Load right operand into d1. 1947 // Load right operand into d1.
1955 if (right_type == BinaryOpIC::INT32) { 1948 if (right_type == BinaryOpIC::INT32) {
1956 __ LoadNumberAsInt32Double( 1949 __ LoadNumberAsInt32Double(
1957 right, d1, heap_number_map, scratch1, d8, miss); 1950 right, d1, heap_number_map, scratch1, d8, miss);
1958 } else { 1951 } else {
1959 Label* fail = (right_type == BinaryOpIC::NUMBER) ? miss : not_numbers; 1952 Label* fail = (right_type == BinaryOpIC::NUMBER) ? miss : not_numbers;
1960 __ LoadNumber(right, d1, heap_number_map, scratch1, fail); 1953 __ LoadNumber(right, d1, heap_number_map, scratch1, fail);
1961 } 1954 }
1962 // Load left operand into d0. 1955 // Load left operand into d0.
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
2053 case Token::SHL: 2046 case Token::SHL:
2054 // Use only the 5 least significant bits of the shift count. 2047 // Use only the 5 least significant bits of the shift count.
2055 __ GetLeastBitsFromInt32(r2, r2, 5); 2048 __ GetLeastBitsFromInt32(r2, r2, 5);
2056 __ mov(r2, Operand(r3, LSL, r2)); 2049 __ mov(r2, Operand(r3, LSL, r2));
2057 break; 2050 break;
2058 default: 2051 default:
2059 UNREACHABLE(); 2052 UNREACHABLE();
2060 } 2053 }
2061 2054
2062 // Check that the *signed* result fits in a smi. 2055 // Check that the *signed* result fits in a smi.
2063 __ add(r3, r2, Operand(0x40000000), SetCC); 2056 __ TrySmiTag(r0, r2, &result_not_a_smi);
2064 __ b(mi, &result_not_a_smi);
2065 __ SmiTag(r0, r2);
2066 __ Ret(); 2057 __ Ret();
2067 2058
2068 // Allocate new heap number for result. 2059 // Allocate new heap number for result.
2069 __ bind(&result_not_a_smi); 2060 __ bind(&result_not_a_smi);
2070 Register result = r5; 2061 Register result = r5;
2071 if (smi_operands) { 2062 if (smi_operands) {
2072 __ AllocateHeapNumber( 2063 __ AllocateHeapNumber(
2073 result, scratch1, scratch2, heap_number_map, gc_required); 2064 result, scratch1, scratch2, heap_number_map, gc_required);
2074 } else { 2065 } else {
2075 BinaryOpStub_GenerateHeapResultAllocation( 2066 BinaryOpStub_GenerateHeapResultAllocation(
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
2115 BinaryOpStub::SmiCodeGenerateHeapNumberResults allow_heapnumber_results, 2106 BinaryOpStub::SmiCodeGenerateHeapNumberResults allow_heapnumber_results,
2116 OverwriteMode mode) { 2107 OverwriteMode mode) {
2117 Label not_smis; 2108 Label not_smis;
2118 2109
2119 Register left = r1; 2110 Register left = r1;
2120 Register right = r0; 2111 Register right = r0;
2121 Register scratch1 = r7; 2112 Register scratch1 = r7;
2122 2113
2123 // Perform combined smi check on both operands. 2114 // Perform combined smi check on both operands.
2124 __ orr(scratch1, left, Operand(right)); 2115 __ orr(scratch1, left, Operand(right));
2125 STATIC_ASSERT(kSmiTag == 0);
2126 __ JumpIfNotSmi(scratch1, &not_smis); 2116 __ JumpIfNotSmi(scratch1, &not_smis);
2127 2117
2128 // If the smi-smi operation results in a smi return is generated. 2118 // If the smi-smi operation results in a smi return is generated.
2129 BinaryOpStub_GenerateSmiSmiOperation(masm, op); 2119 BinaryOpStub_GenerateSmiSmiOperation(masm, op);
2130 2120
2131 // If heap number results are possible generate the result in an allocated 2121 // If heap number results are possible generate the result in an allocated
2132 // heap number. 2122 // heap number.
2133 if (allow_heapnumber_results == BinaryOpStub::ALLOW_HEAPNUMBER_RESULTS) { 2123 if (allow_heapnumber_results == BinaryOpStub::ALLOW_HEAPNUMBER_RESULTS) {
2134 BinaryOpStub_GenerateFPOperation( 2124 BinaryOpStub_GenerateFPOperation(
2135 masm, BinaryOpIC::UNINITIALIZED, BinaryOpIC::UNINITIALIZED, true, 2125 masm, BinaryOpIC::UNINITIALIZED, BinaryOpIC::UNINITIALIZED, true,
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after
2404 : &return_heap_number); 2394 : &return_heap_number);
2405 break; 2395 break;
2406 case Token::SHL: 2396 case Token::SHL:
2407 __ and_(r2, r2, Operand(0x1f)); 2397 __ and_(r2, r2, Operand(0x1f));
2408 __ mov(r2, Operand(r3, LSL, r2)); 2398 __ mov(r2, Operand(r3, LSL, r2));
2409 break; 2399 break;
2410 default: 2400 default:
2411 UNREACHABLE(); 2401 UNREACHABLE();
2412 } 2402 }
2413 2403
2414 // Check if the result fits in a smi. 2404 // Check if the result fits in a smi. If not try to return a heap number.
2415 __ add(scratch1, r2, Operand(0x40000000), SetCC); 2405 // (We know the result is an int32).
2416 // If not try to return a heap number. (We know the result is an int32.) 2406 __ TrySmiTag(r0, r2, &return_heap_number);
2417 __ b(mi, &return_heap_number);
2418 // Tag the result and return.
2419 __ SmiTag(r0, r2);
2420 __ Ret(); 2407 __ Ret();
2421 2408
2422 __ bind(&return_heap_number); 2409 __ bind(&return_heap_number);
2423 heap_number_result = r5; 2410 heap_number_result = r5;
2424 BinaryOpStub_GenerateHeapResultAllocation(masm, 2411 BinaryOpStub_GenerateHeapResultAllocation(masm,
2425 heap_number_result, 2412 heap_number_result,
2426 heap_number_map, 2413 heap_number_map,
2427 scratch1, 2414 scratch1,
2428 scratch2, 2415 scratch2,
2429 &call_runtime, 2416 &call_runtime,
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
2637 const Register cache_entry = r0; 2624 const Register cache_entry = r0;
2638 const bool tagged = (argument_type_ == TAGGED); 2625 const bool tagged = (argument_type_ == TAGGED);
2639 2626
2640 if (tagged) { 2627 if (tagged) {
2641 // Argument is a number and is on stack and in r0. 2628 // Argument is a number and is on stack and in r0.
2642 // Load argument and check if it is a smi. 2629 // Load argument and check if it is a smi.
2643 __ JumpIfNotSmi(r0, &input_not_smi); 2630 __ JumpIfNotSmi(r0, &input_not_smi);
2644 2631
2645 // Input is a smi. Convert to double and load the low and high words 2632 // Input is a smi. Convert to double and load the low and high words
2646 // of the double into r2, r3. 2633 // of the double into r2, r3.
2647 __ IntegerToDoubleConversionWithVFP3(r0, r3, r2); 2634 __ SmiToDouble(d7, r0);
2635 __ vmov(r2, r3, d7);
2648 __ b(&loaded); 2636 __ b(&loaded);
2649 2637
2650 __ bind(&input_not_smi); 2638 __ bind(&input_not_smi);
2651 // Check if input is a HeapNumber. 2639 // Check if input is a HeapNumber.
2652 __ CheckMap(r0, 2640 __ CheckMap(r0,
2653 r1, 2641 r1,
2654 Heap::kHeapNumberMapRootIndex, 2642 Heap::kHeapNumberMapRootIndex,
2655 &calculate, 2643 &calculate,
2656 DONT_DO_SMI_CHECK); 2644 DONT_DO_SMI_CHECK);
2657 // Input is a HeapNumber. Load it to a double register and store the 2645 // Input is a HeapNumber. Load it to a double register and store the
(...skipping 1177 matching lines...) Expand 10 before | Expand all | Expand 10 after
3835 __ b(eq, &adaptor); 3823 __ b(eq, &adaptor);
3836 3824
3837 // Check index against formal parameters count limit passed in 3825 // Check index against formal parameters count limit passed in
3838 // through register r0. Use unsigned comparison to get negative 3826 // through register r0. Use unsigned comparison to get negative
3839 // check for free. 3827 // check for free.
3840 __ cmp(r1, r0); 3828 __ cmp(r1, r0);
3841 __ b(hs, &slow); 3829 __ b(hs, &slow);
3842 3830
3843 // Read the argument from the stack and return it. 3831 // Read the argument from the stack and return it.
3844 __ sub(r3, r0, r1); 3832 __ sub(r3, r0, r1);
3845 __ add(r3, fp, Operand(r3, LSL, kPointerSizeLog2 - kSmiTagSize)); 3833 __ add(r3, fp, Operand::PointerOffsetFromSmiKey(r3));
3846 __ ldr(r0, MemOperand(r3, kDisplacement)); 3834 __ ldr(r0, MemOperand(r3, kDisplacement));
3847 __ Jump(lr); 3835 __ Jump(lr);
3848 3836
3849 // Arguments adaptor case: Check index against actual arguments 3837 // Arguments adaptor case: Check index against actual arguments
3850 // limit found in the arguments adaptor frame. Use unsigned 3838 // limit found in the arguments adaptor frame. Use unsigned
3851 // comparison to get negative check for free. 3839 // comparison to get negative check for free.
3852 __ bind(&adaptor); 3840 __ bind(&adaptor);
3853 __ ldr(r0, MemOperand(r2, ArgumentsAdaptorFrameConstants::kLengthOffset)); 3841 __ ldr(r0, MemOperand(r2, ArgumentsAdaptorFrameConstants::kLengthOffset));
3854 __ cmp(r1, r0); 3842 __ cmp(r1, r0);
3855 __ b(cs, &slow); 3843 __ b(cs, &slow);
3856 3844
3857 // Read the argument from the adaptor frame and return it. 3845 // Read the argument from the adaptor frame and return it.
3858 __ sub(r3, r0, r1); 3846 __ sub(r3, r0, r1);
3859 __ add(r3, r2, Operand(r3, LSL, kPointerSizeLog2 - kSmiTagSize)); 3847 __ add(r3, r2, Operand::PointerOffsetFromSmiKey(r3));
3860 __ ldr(r0, MemOperand(r3, kDisplacement)); 3848 __ ldr(r0, MemOperand(r3, kDisplacement));
3861 __ Jump(lr); 3849 __ Jump(lr);
3862 3850
3863 // Slow-case: Handle non-smi or out-of-bounds access to arguments 3851 // Slow-case: Handle non-smi or out-of-bounds access to arguments
3864 // by calling the runtime system. 3852 // by calling the runtime system.
3865 __ bind(&slow); 3853 __ bind(&slow);
3866 __ push(r1); 3854 __ push(r1);
3867 __ TailCallRuntime(Runtime::kGetArgumentsProperty, 1, 1); 3855 __ TailCallRuntime(Runtime::kGetArgumentsProperty, 1, 1);
3868 } 3856 }
3869 3857
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
4102 __ b(eq, &adaptor_frame); 4090 __ b(eq, &adaptor_frame);
4103 4091
4104 // Get the length from the frame. 4092 // Get the length from the frame.
4105 __ ldr(r1, MemOperand(sp, 0)); 4093 __ ldr(r1, MemOperand(sp, 0));
4106 __ b(&try_allocate); 4094 __ b(&try_allocate);
4107 4095
4108 // Patch the arguments.length and the parameters pointer. 4096 // Patch the arguments.length and the parameters pointer.
4109 __ bind(&adaptor_frame); 4097 __ bind(&adaptor_frame);
4110 __ ldr(r1, MemOperand(r2, ArgumentsAdaptorFrameConstants::kLengthOffset)); 4098 __ ldr(r1, MemOperand(r2, ArgumentsAdaptorFrameConstants::kLengthOffset));
4111 __ str(r1, MemOperand(sp, 0)); 4099 __ str(r1, MemOperand(sp, 0));
4112 __ add(r3, r2, Operand(r1, LSL, kPointerSizeLog2 - kSmiTagSize)); 4100 __ add(r3, r2, Operand::PointerOffsetFromSmiKey(r1));
4113 __ add(r3, r3, Operand(StandardFrameConstants::kCallerSPOffset)); 4101 __ add(r3, r3, Operand(StandardFrameConstants::kCallerSPOffset));
4114 __ str(r3, MemOperand(sp, 1 * kPointerSize)); 4102 __ str(r3, MemOperand(sp, 1 * kPointerSize));
4115 4103
4116 // Try the new space allocation. Start out with computing the size 4104 // Try the new space allocation. Start out with computing the size
4117 // of the arguments object and the elements array in words. 4105 // of the arguments object and the elements array in words.
4118 Label add_arguments_object; 4106 Label add_arguments_object;
4119 __ bind(&try_allocate); 4107 __ bind(&try_allocate);
4120 __ cmp(r1, Operand::Zero()); 4108 __ SmiUntag(r1, SetCC);
4121 __ b(eq, &add_arguments_object); 4109 __ b(eq, &add_arguments_object);
4122 __ mov(r1, Operand(r1, LSR, kSmiTagSize));
4123 __ add(r1, r1, Operand(FixedArray::kHeaderSize / kPointerSize)); 4110 __ add(r1, r1, Operand(FixedArray::kHeaderSize / kPointerSize));
4124 __ bind(&add_arguments_object); 4111 __ bind(&add_arguments_object);
4125 __ add(r1, r1, Operand(Heap::kArgumentsObjectSizeStrict / kPointerSize)); 4112 __ add(r1, r1, Operand(Heap::kArgumentsObjectSizeStrict / kPointerSize));
4126 4113
4127 // Do the allocation of both objects in one go. 4114 // Do the allocation of both objects in one go.
4128 __ Allocate(r1, r0, r2, r3, &runtime, 4115 __ Allocate(r1, r0, r2, r3, &runtime,
4129 static_cast<AllocationFlags>(TAG_OBJECT | SIZE_IN_WORDS)); 4116 static_cast<AllocationFlags>(TAG_OBJECT | SIZE_IN_WORDS));
4130 4117
4131 // Get the arguments boilerplate from the current native context. 4118 // Get the arguments boilerplate from the current native context.
4132 __ ldr(r4, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); 4119 __ ldr(r4, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
(...skipping 18 matching lines...) Expand all
4151 // Get the parameters pointer from the stack. 4138 // Get the parameters pointer from the stack.
4152 __ ldr(r2, MemOperand(sp, 1 * kPointerSize)); 4139 __ ldr(r2, MemOperand(sp, 1 * kPointerSize));
4153 4140
4154 // Set up the elements pointer in the allocated arguments object and 4141 // Set up the elements pointer in the allocated arguments object and
4155 // initialize the header in the elements fixed array. 4142 // initialize the header in the elements fixed array.
4156 __ add(r4, r0, Operand(Heap::kArgumentsObjectSizeStrict)); 4143 __ add(r4, r0, Operand(Heap::kArgumentsObjectSizeStrict));
4157 __ str(r4, FieldMemOperand(r0, JSObject::kElementsOffset)); 4144 __ str(r4, FieldMemOperand(r0, JSObject::kElementsOffset));
4158 __ LoadRoot(r3, Heap::kFixedArrayMapRootIndex); 4145 __ LoadRoot(r3, Heap::kFixedArrayMapRootIndex);
4159 __ str(r3, FieldMemOperand(r4, FixedArray::kMapOffset)); 4146 __ str(r3, FieldMemOperand(r4, FixedArray::kMapOffset));
4160 __ str(r1, FieldMemOperand(r4, FixedArray::kLengthOffset)); 4147 __ str(r1, FieldMemOperand(r4, FixedArray::kLengthOffset));
4161 // Untag the length for the loop. 4148 __ SmiUntag(r1);
4162 __ mov(r1, Operand(r1, LSR, kSmiTagSize));
4163 4149
4164 // Copy the fixed array slots. 4150 // Copy the fixed array slots.
4165 Label loop; 4151 Label loop;
4166 // Set up r4 to point to the first array slot. 4152 // Set up r4 to point to the first array slot.
4167 __ add(r4, r4, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); 4153 __ add(r4, r4, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
4168 __ bind(&loop); 4154 __ bind(&loop);
4169 // Pre-decrement r2 with kPointerSize on each iteration. 4155 // Pre-decrement r2 with kPointerSize on each iteration.
4170 // Pre-decrement in order to skip receiver. 4156 // Pre-decrement in order to skip receiver.
4171 __ ldr(r3, MemOperand(r2, kPointerSize, NegPreIndex)); 4157 __ ldr(r3, MemOperand(r2, kPointerSize, NegPreIndex));
4172 // Post-increment r4 with kPointerSize on each iteration. 4158 // Post-increment r4 with kPointerSize on each iteration.
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
4221 ExternalReference::address_of_regexp_stack_memory_address(isolate); 4207 ExternalReference::address_of_regexp_stack_memory_address(isolate);
4222 ExternalReference address_of_regexp_stack_memory_size = 4208 ExternalReference address_of_regexp_stack_memory_size =
4223 ExternalReference::address_of_regexp_stack_memory_size(isolate); 4209 ExternalReference::address_of_regexp_stack_memory_size(isolate);
4224 __ mov(r0, Operand(address_of_regexp_stack_memory_size)); 4210 __ mov(r0, Operand(address_of_regexp_stack_memory_size));
4225 __ ldr(r0, MemOperand(r0, 0)); 4211 __ ldr(r0, MemOperand(r0, 0));
4226 __ cmp(r0, Operand::Zero()); 4212 __ cmp(r0, Operand::Zero());
4227 __ b(eq, &runtime); 4213 __ b(eq, &runtime);
4228 4214
4229 // Check that the first argument is a JSRegExp object. 4215 // Check that the first argument is a JSRegExp object.
4230 __ ldr(r0, MemOperand(sp, kJSRegExpOffset)); 4216 __ ldr(r0, MemOperand(sp, kJSRegExpOffset));
4231 STATIC_ASSERT(kSmiTag == 0);
4232 __ JumpIfSmi(r0, &runtime); 4217 __ JumpIfSmi(r0, &runtime);
4233 __ CompareObjectType(r0, r1, r1, JS_REGEXP_TYPE); 4218 __ CompareObjectType(r0, r1, r1, JS_REGEXP_TYPE);
4234 __ b(ne, &runtime); 4219 __ b(ne, &runtime);
4235 4220
4236 // Check that the RegExp has been compiled (data contains a fixed array). 4221 // Check that the RegExp has been compiled (data contains a fixed array).
4237 __ ldr(regexp_data, FieldMemOperand(r0, JSRegExp::kDataOffset)); 4222 __ ldr(regexp_data, FieldMemOperand(r0, JSRegExp::kDataOffset));
4238 if (FLAG_debug_code) { 4223 if (FLAG_debug_code) {
4239 __ tst(regexp_data, Operand(kSmiTagMask)); 4224 __ SmiTst(regexp_data);
4240 __ Check(ne, "Unexpected type for RegExp data, FixedArray expected"); 4225 __ Check(ne, "Unexpected type for RegExp data, FixedArray expected");
4241 __ CompareObjectType(regexp_data, r0, r0, FIXED_ARRAY_TYPE); 4226 __ CompareObjectType(regexp_data, r0, r0, FIXED_ARRAY_TYPE);
4242 __ Check(eq, "Unexpected type for RegExp data, FixedArray expected"); 4227 __ Check(eq, "Unexpected type for RegExp data, FixedArray expected");
4243 } 4228 }
4244 4229
4245 // regexp_data: RegExp data (FixedArray) 4230 // regexp_data: RegExp data (FixedArray)
4246 // Check the type of the RegExp. Only continue if type is JSRegExp::IRREGEXP. 4231 // Check the type of the RegExp. Only continue if type is JSRegExp::IRREGEXP.
4247 __ ldr(r0, FieldMemOperand(regexp_data, JSRegExp::kDataTagOffset)); 4232 __ ldr(r0, FieldMemOperand(regexp_data, JSRegExp::kDataTagOffset));
4248 __ cmp(r0, Operand(Smi::FromInt(JSRegExp::IRREGEXP))); 4233 __ cmp(r0, Operand(Smi::FromInt(JSRegExp::IRREGEXP)));
4249 __ b(ne, &runtime); 4234 __ b(ne, &runtime);
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
4334 // subject: sequential subject string (or look-alike, external string) 4319 // subject: sequential subject string (or look-alike, external string)
4335 // r3: original subject string 4320 // r3: original subject string
4336 // Load previous index and check range before r3 is overwritten. We have to 4321 // Load previous index and check range before r3 is overwritten. We have to
4337 // use r3 instead of subject here because subject might have been only made 4322 // use r3 instead of subject here because subject might have been only made
4338 // to look like a sequential string when it actually is an external string. 4323 // to look like a sequential string when it actually is an external string.
4339 __ ldr(r1, MemOperand(sp, kPreviousIndexOffset)); 4324 __ ldr(r1, MemOperand(sp, kPreviousIndexOffset));
4340 __ JumpIfNotSmi(r1, &runtime); 4325 __ JumpIfNotSmi(r1, &runtime);
4341 __ ldr(r3, FieldMemOperand(r3, String::kLengthOffset)); 4326 __ ldr(r3, FieldMemOperand(r3, String::kLengthOffset));
4342 __ cmp(r3, Operand(r1)); 4327 __ cmp(r3, Operand(r1));
4343 __ b(ls, &runtime); 4328 __ b(ls, &runtime);
4344 __ mov(r1, Operand(r1, ASR, kSmiTagSize)); 4329 __ SmiUntag(r1);
4345 4330
4346 STATIC_ASSERT(4 == kOneByteStringTag); 4331 STATIC_ASSERT(4 == kOneByteStringTag);
4347 STATIC_ASSERT(kTwoByteStringTag == 0); 4332 STATIC_ASSERT(kTwoByteStringTag == 0);
4348 __ and_(r0, r0, Operand(kStringEncodingMask)); 4333 __ and_(r0, r0, Operand(kStringEncodingMask));
4349 __ mov(r3, Operand(r0, ASR, 2), SetCC); 4334 __ mov(r3, Operand(r0, ASR, 2), SetCC);
4350 __ ldr(r7, FieldMemOperand(regexp_data, JSRegExp::kDataAsciiCodeOffset), ne); 4335 __ ldr(r7, FieldMemOperand(regexp_data, JSRegExp::kDataAsciiCodeOffset), ne);
4351 __ ldr(r7, FieldMemOperand(regexp_data, JSRegExp::kDataUC16CodeOffset), eq); 4336 __ ldr(r7, FieldMemOperand(regexp_data, JSRegExp::kDataUC16CodeOffset), eq);
4352 4337
4353 // (E) Carry on. String handling is done. 4338 // (E) Carry on. String handling is done.
4354 // r7: irregexp code 4339 // r7: irregexp code
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
4409 // the previous fp onto the stack and moves up sp by 2 * kPointerSize.) 4394 // the previous fp onto the stack and moves up sp by 2 * kPointerSize.)
4410 __ ldr(subject, MemOperand(fp, kSubjectOffset + 2 * kPointerSize)); 4395 __ ldr(subject, MemOperand(fp, kSubjectOffset + 2 * kPointerSize));
4411 // If slice offset is not 0, load the length from the original sliced string. 4396 // If slice offset is not 0, load the length from the original sliced string.
4412 // Argument 4, r3: End of string data 4397 // Argument 4, r3: End of string data
4413 // Argument 3, r2: Start of string data 4398 // Argument 3, r2: Start of string data
4414 // Prepare start and end index of the input. 4399 // Prepare start and end index of the input.
4415 __ add(r9, r8, Operand(r9, LSL, r3)); 4400 __ add(r9, r8, Operand(r9, LSL, r3));
4416 __ add(r2, r9, Operand(r1, LSL, r3)); 4401 __ add(r2, r9, Operand(r1, LSL, r3));
4417 4402
4418 __ ldr(r8, FieldMemOperand(subject, String::kLengthOffset)); 4403 __ ldr(r8, FieldMemOperand(subject, String::kLengthOffset));
4419 __ mov(r8, Operand(r8, ASR, kSmiTagSize)); 4404 __ SmiUntag(r8);
4420 __ add(r3, r9, Operand(r8, LSL, r3)); 4405 __ add(r3, r9, Operand(r8, LSL, r3));
4421 4406
4422 // Argument 2 (r1): Previous index. 4407 // Argument 2 (r1): Previous index.
4423 // Already there 4408 // Already there
4424 4409
4425 // Argument 1 (r0): Subject string. 4410 // Argument 1 (r0): Subject string.
4426 __ mov(r0, subject); 4411 __ mov(r0, subject);
4427 4412
4428 // Locate the code entry and call it. 4413 // Locate the code entry and call it.
4429 __ add(r7, r7, Operand(Code::kHeaderSize - kHeapObjectTag)); 4414 __ add(r7, r7, Operand(Code::kHeaderSize - kHeapObjectTag));
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
4496 __ ldr(last_match_info_elements, 4481 __ ldr(last_match_info_elements,
4497 FieldMemOperand(r0, JSArray::kElementsOffset)); 4482 FieldMemOperand(r0, JSArray::kElementsOffset));
4498 __ ldr(r0, FieldMemOperand(last_match_info_elements, HeapObject::kMapOffset)); 4483 __ ldr(r0, FieldMemOperand(last_match_info_elements, HeapObject::kMapOffset));
4499 __ CompareRoot(r0, Heap::kFixedArrayMapRootIndex); 4484 __ CompareRoot(r0, Heap::kFixedArrayMapRootIndex);
4500 __ b(ne, &runtime); 4485 __ b(ne, &runtime);
4501 // Check that the last match info has space for the capture registers and the 4486 // Check that the last match info has space for the capture registers and the
4502 // additional information. 4487 // additional information.
4503 __ ldr(r0, 4488 __ ldr(r0,
4504 FieldMemOperand(last_match_info_elements, FixedArray::kLengthOffset)); 4489 FieldMemOperand(last_match_info_elements, FixedArray::kLengthOffset));
4505 __ add(r2, r1, Operand(RegExpImpl::kLastMatchOverhead)); 4490 __ add(r2, r1, Operand(RegExpImpl::kLastMatchOverhead));
4506 __ cmp(r2, Operand(r0, ASR, kSmiTagSize)); 4491 __ cmp(r2, Operand::SmiUntag(r0));
4507 __ b(gt, &runtime); 4492 __ b(gt, &runtime);
4508 4493
4509 // r1: number of capture registers 4494 // r1: number of capture registers
4510 // r4: subject string 4495 // r4: subject string
4511 // Store the capture count. 4496 // Store the capture count.
4512 __ mov(r2, Operand(r1, LSL, kSmiTagSize + kSmiShiftSize)); // To smi. 4497 __ SmiTag(r2, r1);
4513 __ str(r2, FieldMemOperand(last_match_info_elements, 4498 __ str(r2, FieldMemOperand(last_match_info_elements,
4514 RegExpImpl::kLastCaptureCountOffset)); 4499 RegExpImpl::kLastCaptureCountOffset));
4515 // Store last subject and last input. 4500 // Store last subject and last input.
4516 __ str(subject, 4501 __ str(subject,
4517 FieldMemOperand(last_match_info_elements, 4502 FieldMemOperand(last_match_info_elements,
4518 RegExpImpl::kLastSubjectOffset)); 4503 RegExpImpl::kLastSubjectOffset));
4519 __ mov(r2, subject); 4504 __ mov(r2, subject);
4520 __ RecordWriteField(last_match_info_elements, 4505 __ RecordWriteField(last_match_info_elements,
4521 RegExpImpl::kLastSubjectOffset, 4506 RegExpImpl::kLastSubjectOffset,
4522 subject, 4507 subject,
(...skipping 23 matching lines...) Expand all
4546 // counts down until wraping after zero. 4531 // counts down until wraping after zero.
4547 __ add(r0, 4532 __ add(r0,
4548 last_match_info_elements, 4533 last_match_info_elements,
4549 Operand(RegExpImpl::kFirstCaptureOffset - kHeapObjectTag)); 4534 Operand(RegExpImpl::kFirstCaptureOffset - kHeapObjectTag));
4550 __ bind(&next_capture); 4535 __ bind(&next_capture);
4551 __ sub(r1, r1, Operand(1), SetCC); 4536 __ sub(r1, r1, Operand(1), SetCC);
4552 __ b(mi, &done); 4537 __ b(mi, &done);
4553 // Read the value from the static offsets vector buffer. 4538 // Read the value from the static offsets vector buffer.
4554 __ ldr(r3, MemOperand(r2, kPointerSize, PostIndex)); 4539 __ ldr(r3, MemOperand(r2, kPointerSize, PostIndex));
4555 // Store the smi value in the last match info. 4540 // Store the smi value in the last match info.
4556 __ mov(r3, Operand(r3, LSL, kSmiTagSize)); 4541 __ SmiTag(r3);
4557 __ str(r3, MemOperand(r0, kPointerSize, PostIndex)); 4542 __ str(r3, MemOperand(r0, kPointerSize, PostIndex));
4558 __ jmp(&next_capture); 4543 __ jmp(&next_capture);
4559 __ bind(&done); 4544 __ bind(&done);
4560 4545
4561 // Return last match info. 4546 // Return last match info.
4562 __ ldr(r0, MemOperand(sp, kLastMatchInfoOffset)); 4547 __ ldr(r0, MemOperand(sp, kLastMatchInfoOffset));
4563 __ add(sp, sp, Operand(4 * kPointerSize)); 4548 __ add(sp, sp, Operand(4 * kPointerSize));
4564 __ Ret(); 4549 __ Ret();
4565 4550
4566 // Do the runtime call to execute the regexp. 4551 // Do the runtime call to execute the regexp.
(...skipping 27 matching lines...) Expand all
4594 4579
4595 // (8) Short external string or not a string? If yes, bail out to runtime. 4580 // (8) Short external string or not a string? If yes, bail out to runtime.
4596 __ bind(&not_long_external); 4581 __ bind(&not_long_external);
4597 STATIC_ASSERT(kNotStringTag != 0 && kShortExternalStringTag !=0); 4582 STATIC_ASSERT(kNotStringTag != 0 && kShortExternalStringTag !=0);
4598 __ tst(r1, Operand(kIsNotStringMask | kShortExternalStringMask)); 4583 __ tst(r1, Operand(kIsNotStringMask | kShortExternalStringMask));
4599 __ b(ne, &runtime); 4584 __ b(ne, &runtime);
4600 4585
4601 // (9) Sliced string. Replace subject with parent. Go to (4). 4586 // (9) Sliced string. Replace subject with parent. Go to (4).
4602 // Load offset into r9 and replace subject string with parent. 4587 // Load offset into r9 and replace subject string with parent.
4603 __ ldr(r9, FieldMemOperand(subject, SlicedString::kOffsetOffset)); 4588 __ ldr(r9, FieldMemOperand(subject, SlicedString::kOffsetOffset));
4604 __ mov(r9, Operand(r9, ASR, kSmiTagSize)); 4589 __ SmiUntag(r9);
4605 __ ldr(subject, FieldMemOperand(subject, SlicedString::kParentOffset)); 4590 __ ldr(subject, FieldMemOperand(subject, SlicedString::kParentOffset));
4606 __ jmp(&check_underlying); // Go to (4). 4591 __ jmp(&check_underlying); // Go to (4).
4607 #endif // V8_INTERPRETED_REGEXP 4592 #endif // V8_INTERPRETED_REGEXP
4608 } 4593 }
4609 4594
4610 4595
4611 void RegExpConstructResultStub::Generate(MacroAssembler* masm) { 4596 void RegExpConstructResultStub::Generate(MacroAssembler* masm) {
4612 const int kMaxInlineLength = 100; 4597 const int kMaxInlineLength = 100;
4613 Label slowcase; 4598 Label slowcase;
4614 Label done; 4599 Label done;
4615 Factory* factory = masm->isolate()->factory(); 4600 Factory* factory = masm->isolate()->factory();
4616 4601
4617 __ ldr(r1, MemOperand(sp, kPointerSize * 2)); 4602 __ ldr(r1, MemOperand(sp, kPointerSize * 2));
4618 STATIC_ASSERT(kSmiTag == 0); 4603 STATIC_ASSERT(kSmiTag == 0);
4619 STATIC_ASSERT(kSmiTagSize == 1); 4604 STATIC_ASSERT(kSmiTagSize == 1);
4620 __ JumpIfNotSmi(r1, &slowcase); 4605 __ JumpIfNotSmi(r1, &slowcase);
4621 __ cmp(r1, Operand(Smi::FromInt(kMaxInlineLength))); 4606 __ cmp(r1, Operand(Smi::FromInt(kMaxInlineLength)));
4622 __ b(hi, &slowcase); 4607 __ b(hi, &slowcase);
4623 // Smi-tagging is equivalent to multiplying by 2. 4608 // Smi-tagging is equivalent to multiplying by 2.
4624 // Allocate RegExpResult followed by FixedArray with size in ebx. 4609 // Allocate RegExpResult followed by FixedArray with size in ebx.
4625 // JSArray: [Map][empty properties][Elements][Length-smi][index][input] 4610 // JSArray: [Map][empty properties][Elements][Length-smi][index][input]
4626 // Elements: [Map][Length][..elements..] 4611 // Elements: [Map][Length][..elements..]
4627 // Size of JSArray with two in-object properties and the header of a 4612 // Size of JSArray with two in-object properties and the header of a
4628 // FixedArray. 4613 // FixedArray.
4629 int objects_size = 4614 int objects_size =
4630 (JSRegExpResult::kSize + FixedArray::kHeaderSize) / kPointerSize; 4615 (JSRegExpResult::kSize + FixedArray::kHeaderSize) / kPointerSize;
4631 __ mov(r5, Operand(r1, LSR, kSmiTagSize + kSmiShiftSize)); 4616 __ SmiUntag(r5, r1);
4632 __ add(r2, r5, Operand(objects_size)); 4617 __ add(r2, r5, Operand(objects_size));
4633 __ Allocate( 4618 __ Allocate(
4634 r2, // In: Size, in words. 4619 r2, // In: Size, in words.
4635 r0, // Out: Start of allocation (tagged). 4620 r0, // Out: Start of allocation (tagged).
4636 r3, // Scratch register. 4621 r3, // Scratch register.
4637 r4, // Scratch register. 4622 r4, // Scratch register.
4638 &slowcase, 4623 &slowcase,
4639 static_cast<AllocationFlags>(TAG_OBJECT | SIZE_IN_WORDS)); 4624 static_cast<AllocationFlags>(TAG_OBJECT | SIZE_IN_WORDS));
4640 // r0: Start of allocated area, object-tagged. 4625 // r0: Start of allocated area, object-tagged.
4641 // r1: Number of elements in array, as smi. 4626 // r1: Number of elements in array, as smi.
(...skipping 22 matching lines...) Expand all
4664 4649
4665 // Fill out the elements FixedArray. 4650 // Fill out the elements FixedArray.
4666 // r0: JSArray, tagged. 4651 // r0: JSArray, tagged.
4667 // r3: FixedArray, tagged. 4652 // r3: FixedArray, tagged.
4668 // r5: Number of elements in array, untagged. 4653 // r5: Number of elements in array, untagged.
4669 4654
4670 // Set map. 4655 // Set map.
4671 __ mov(r2, Operand(factory->fixed_array_map())); 4656 __ mov(r2, Operand(factory->fixed_array_map()));
4672 __ str(r2, FieldMemOperand(r3, HeapObject::kMapOffset)); 4657 __ str(r2, FieldMemOperand(r3, HeapObject::kMapOffset));
4673 // Set FixedArray length. 4658 // Set FixedArray length.
4674 __ mov(r6, Operand(r5, LSL, kSmiTagSize)); 4659 __ SmiTag(r6, r5);
4675 __ str(r6, FieldMemOperand(r3, FixedArray::kLengthOffset)); 4660 __ str(r6, FieldMemOperand(r3, FixedArray::kLengthOffset));
4676 // Fill contents of fixed-array with undefined. 4661 // Fill contents of fixed-array with undefined.
4677 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex); 4662 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex);
4678 __ add(r3, r3, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); 4663 __ add(r3, r3, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
4679 // Fill fixed array elements with undefined. 4664 // Fill fixed array elements with undefined.
4680 // r0: JSArray, tagged. 4665 // r0: JSArray, tagged.
4681 // r2: undefined. 4666 // r2: undefined.
4682 // r3: Start of elements in FixedArray. 4667 // r3: Start of elements in FixedArray.
4683 // r5: Number of elements to fill. 4668 // r5: Number of elements to fill.
4684 Label loop; 4669 Label loop;
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after
4981 4966
4982 // If the index is non-smi trigger the non-smi case. 4967 // If the index is non-smi trigger the non-smi case.
4983 __ JumpIfNotSmi(index_, &index_not_smi_); 4968 __ JumpIfNotSmi(index_, &index_not_smi_);
4984 __ bind(&got_smi_index_); 4969 __ bind(&got_smi_index_);
4985 4970
4986 // Check for index out of range. 4971 // Check for index out of range.
4987 __ ldr(ip, FieldMemOperand(object_, String::kLengthOffset)); 4972 __ ldr(ip, FieldMemOperand(object_, String::kLengthOffset));
4988 __ cmp(ip, Operand(index_)); 4973 __ cmp(ip, Operand(index_));
4989 __ b(ls, index_out_of_range_); 4974 __ b(ls, index_out_of_range_);
4990 4975
4991 __ mov(index_, Operand(index_, ASR, kSmiTagSize)); 4976 __ SmiUntag(index_);
4992 4977
4993 StringCharLoadGenerator::Generate(masm, 4978 StringCharLoadGenerator::Generate(masm,
4994 object_, 4979 object_,
4995 index_, 4980 index_,
4996 result_, 4981 result_,
4997 &call_runtime_); 4982 &call_runtime_);
4998 4983
4999 __ mov(result_, Operand(result_, LSL, kSmiTagSize)); 4984 __ SmiTag(result_);
5000 __ bind(&exit_); 4985 __ bind(&exit_);
5001 } 4986 }
5002 4987
5003 4988
5004 void StringCharCodeAtGenerator::GenerateSlow( 4989 void StringCharCodeAtGenerator::GenerateSlow(
5005 MacroAssembler* masm, 4990 MacroAssembler* masm,
5006 const RuntimeCallHelper& call_helper) { 4991 const RuntimeCallHelper& call_helper) {
5007 __ Abort("Unexpected fallthrough to CharCodeAt slow case"); 4992 __ Abort("Unexpected fallthrough to CharCodeAt slow case");
5008 4993
5009 // Index is not a smi. 4994 // Index is not a smi.
(...skipping 25 matching lines...) Expand all
5035 // If index is still not a smi, it must be out of range. 5020 // If index is still not a smi, it must be out of range.
5036 __ JumpIfNotSmi(index_, index_out_of_range_); 5021 __ JumpIfNotSmi(index_, index_out_of_range_);
5037 // Otherwise, return to the fast path. 5022 // Otherwise, return to the fast path.
5038 __ jmp(&got_smi_index_); 5023 __ jmp(&got_smi_index_);
5039 5024
5040 // Call runtime. We get here when the receiver is a string and the 5025 // Call runtime. We get here when the receiver is a string and the
5041 // index is a number, but the code of getting the actual character 5026 // index is a number, but the code of getting the actual character
5042 // is too complex (e.g., when the string needs to be flattened). 5027 // is too complex (e.g., when the string needs to be flattened).
5043 __ bind(&call_runtime_); 5028 __ bind(&call_runtime_);
5044 call_helper.BeforeCall(masm); 5029 call_helper.BeforeCall(masm);
5045 __ mov(index_, Operand(index_, LSL, kSmiTagSize)); 5030 __ SmiTag(index_);
5046 __ Push(object_, index_); 5031 __ Push(object_, index_);
5047 __ CallRuntime(Runtime::kStringCharCodeAt, 2); 5032 __ CallRuntime(Runtime::kStringCharCodeAt, 2);
5048 __ Move(result_, r0); 5033 __ Move(result_, r0);
5049 call_helper.AfterCall(masm); 5034 call_helper.AfterCall(masm);
5050 __ jmp(&exit_); 5035 __ jmp(&exit_);
5051 5036
5052 __ Abort("Unexpected fallthrough from CharCodeAt slow case"); 5037 __ Abort("Unexpected fallthrough from CharCodeAt slow case");
5053 } 5038 }
5054 5039
5055 5040
5056 // ------------------------------------------------------------------------- 5041 // -------------------------------------------------------------------------
5057 // StringCharFromCodeGenerator 5042 // StringCharFromCodeGenerator
5058 5043
5059 void StringCharFromCodeGenerator::GenerateFast(MacroAssembler* masm) { 5044 void StringCharFromCodeGenerator::GenerateFast(MacroAssembler* masm) {
5060 // Fast case of Heap::LookupSingleCharacterStringFromCode. 5045 // Fast case of Heap::LookupSingleCharacterStringFromCode.
5061 STATIC_ASSERT(kSmiTag == 0); 5046 STATIC_ASSERT(kSmiTag == 0);
5062 STATIC_ASSERT(kSmiShiftSize == 0); 5047 STATIC_ASSERT(kSmiShiftSize == 0);
5063 ASSERT(IsPowerOf2(String::kMaxOneByteCharCode + 1)); 5048 ASSERT(IsPowerOf2(String::kMaxOneByteCharCode + 1));
5064 __ tst(code_, 5049 __ tst(code_,
5065 Operand(kSmiTagMask | 5050 Operand(kSmiTagMask |
5066 ((~String::kMaxOneByteCharCode) << kSmiTagSize))); 5051 ((~String::kMaxOneByteCharCode) << kSmiTagSize)));
5067 __ b(ne, &slow_case_); 5052 __ b(ne, &slow_case_);
5068 5053
5069 __ LoadRoot(result_, Heap::kSingleCharacterStringCacheRootIndex); 5054 __ LoadRoot(result_, Heap::kSingleCharacterStringCacheRootIndex);
5070 // At this point code register contains smi tagged ASCII char code. 5055 // At this point code register contains smi tagged ASCII char code.
5071 STATIC_ASSERT(kSmiTag == 0); 5056 __ add(result_, result_, Operand::PointerOffsetFromSmiKey(code_));
5072 __ add(result_, result_, Operand(code_, LSL, kPointerSizeLog2 - kSmiTagSize));
5073 __ ldr(result_, FieldMemOperand(result_, FixedArray::kHeaderSize)); 5057 __ ldr(result_, FieldMemOperand(result_, FixedArray::kHeaderSize));
5074 __ CompareRoot(result_, Heap::kUndefinedValueRootIndex); 5058 __ CompareRoot(result_, Heap::kUndefinedValueRootIndex);
5075 __ b(eq, &slow_case_); 5059 __ b(eq, &slow_case_);
5076 __ bind(&exit_); 5060 __ bind(&exit_);
5077 } 5061 }
5078 5062
5079 5063
5080 void StringCharFromCodeGenerator::GenerateSlow( 5064 void StringCharFromCodeGenerator::GenerateSlow(
5081 MacroAssembler* masm, 5065 MacroAssembler* masm,
5082 const RuntimeCallHelper& call_helper) { 5066 const RuntimeCallHelper& call_helper) {
(...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after
5487 // We want to bailout to runtime here if From is negative. In that case, the 5471 // We want to bailout to runtime here if From is negative. In that case, the
5488 // next instruction is not executed and we fall through to bailing out to 5472 // next instruction is not executed and we fall through to bailing out to
5489 // runtime. 5473 // runtime.
5490 // Executed if both r2 and r3 are untagged integers. 5474 // Executed if both r2 and r3 are untagged integers.
5491 __ sub(r2, r2, Operand(r3), SetCC, cc); 5475 __ sub(r2, r2, Operand(r3), SetCC, cc);
5492 // One of the above un-smis or the above SUB could have set N==1. 5476 // One of the above un-smis or the above SUB could have set N==1.
5493 __ b(mi, &runtime); // Either "from" or "to" is not an smi, or from > to. 5477 __ b(mi, &runtime); // Either "from" or "to" is not an smi, or from > to.
5494 5478
5495 // Make sure first argument is a string. 5479 // Make sure first argument is a string.
5496 __ ldr(r0, MemOperand(sp, kStringOffset)); 5480 __ ldr(r0, MemOperand(sp, kStringOffset));
5497 STATIC_ASSERT(kSmiTag == 0);
5498 // Do a JumpIfSmi, but fold its jump into the subsequent string test. 5481 // Do a JumpIfSmi, but fold its jump into the subsequent string test.
5499 __ tst(r0, Operand(kSmiTagMask)); 5482 __ SmiTst(r0);
5500 Condition is_string = masm->IsObjectStringType(r0, r1, ne); 5483 Condition is_string = masm->IsObjectStringType(r0, r1, ne);
5501 ASSERT(is_string == eq); 5484 ASSERT(is_string == eq);
5502 __ b(NegateCondition(is_string), &runtime); 5485 __ b(NegateCondition(is_string), &runtime);
5503 5486
5504 Label single_char; 5487 Label single_char;
5505 __ cmp(r2, Operand(1)); 5488 __ cmp(r2, Operand(1));
5506 __ b(eq, &single_char); 5489 __ b(eq, &single_char);
5507 5490
5508 // Short-cut for the case of trivial substring. 5491 // Short-cut for the case of trivial substring.
5509 Label return_r0; 5492 Label return_r0;
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after
5886 __ cmp(r3, Operand(Smi::FromInt(0)), ne); 5869 __ cmp(r3, Operand(Smi::FromInt(0)), ne);
5887 __ b(ne, &strings_not_empty); // If either string was empty, return r0. 5870 __ b(ne, &strings_not_empty); // If either string was empty, return r0.
5888 5871
5889 __ IncrementCounter(counters->string_add_native(), 1, r2, r3); 5872 __ IncrementCounter(counters->string_add_native(), 1, r2, r3);
5890 __ add(sp, sp, Operand(2 * kPointerSize)); 5873 __ add(sp, sp, Operand(2 * kPointerSize));
5891 __ Ret(); 5874 __ Ret();
5892 5875
5893 __ bind(&strings_not_empty); 5876 __ bind(&strings_not_empty);
5894 } 5877 }
5895 5878
5896 __ mov(r2, Operand(r2, ASR, kSmiTagSize)); 5879 __ SmiUntag(r2);
5897 __ mov(r3, Operand(r3, ASR, kSmiTagSize)); 5880 __ SmiUntag(r3);
5898 // Both strings are non-empty. 5881 // Both strings are non-empty.
5899 // r0: first string 5882 // r0: first string
5900 // r1: second string 5883 // r1: second string
5901 // r2: length of first string 5884 // r2: length of first string
5902 // r3: length of second string 5885 // r3: length of second string
5903 // r4: first string instance type (if flags_ == NO_STRING_ADD_FLAGS) 5886 // r4: first string instance type (if flags_ == NO_STRING_ADD_FLAGS)
5904 // r5: second string instance type (if flags_ == NO_STRING_ADD_FLAGS) 5887 // r5: second string instance type (if flags_ == NO_STRING_ADD_FLAGS)
5905 // Look at the length of the result of adding the two strings. 5888 // Look at the length of the result of adding the two strings.
5906 Label string_add_flat_result, longer_than_two; 5889 Label string_add_flat_result, longer_than_two;
5907 // Adding two lengths can't overflow. 5890 // Adding two lengths can't overflow.
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after
6229 Label miss; 6212 Label miss;
6230 __ orr(r2, r1, r0); 6213 __ orr(r2, r1, r0);
6231 __ JumpIfNotSmi(r2, &miss); 6214 __ JumpIfNotSmi(r2, &miss);
6232 6215
6233 if (GetCondition() == eq) { 6216 if (GetCondition() == eq) {
6234 // For equality we do not care about the sign of the result. 6217 // For equality we do not care about the sign of the result.
6235 __ sub(r0, r0, r1, SetCC); 6218 __ sub(r0, r0, r1, SetCC);
6236 } else { 6219 } else {
6237 // Untag before subtracting to avoid handling overflow. 6220 // Untag before subtracting to avoid handling overflow.
6238 __ SmiUntag(r1); 6221 __ SmiUntag(r1);
6239 __ sub(r0, r1, SmiUntagOperand(r0)); 6222 __ sub(r0, r1, Operand::SmiUntag(r0));
6240 } 6223 }
6241 __ Ret(); 6224 __ Ret();
6242 6225
6243 __ bind(&miss); 6226 __ bind(&miss);
6244 GenerateMiss(masm); 6227 GenerateMiss(masm);
6245 } 6228 }
6246 6229
6247 6230
6248 void ICCompareStub::GenerateNumbers(MacroAssembler* masm) { 6231 void ICCompareStub::GenerateNumbers(MacroAssembler* masm) {
6249 ASSERT(state_ == CompareIC::NUMBER); 6232 ASSERT(state_ == CompareIC::NUMBER);
(...skipping 13 matching lines...) Expand all
6263 // stub if NaN is involved. 6246 // stub if NaN is involved.
6264 // Load left and right operand. 6247 // Load left and right operand.
6265 Label done, left, left_smi, right_smi; 6248 Label done, left, left_smi, right_smi;
6266 __ JumpIfSmi(r0, &right_smi); 6249 __ JumpIfSmi(r0, &right_smi);
6267 __ CheckMap(r0, r2, Heap::kHeapNumberMapRootIndex, &maybe_undefined1, 6250 __ CheckMap(r0, r2, Heap::kHeapNumberMapRootIndex, &maybe_undefined1,
6268 DONT_DO_SMI_CHECK); 6251 DONT_DO_SMI_CHECK);
6269 __ sub(r2, r0, Operand(kHeapObjectTag)); 6252 __ sub(r2, r0, Operand(kHeapObjectTag));
6270 __ vldr(d1, r2, HeapNumber::kValueOffset); 6253 __ vldr(d1, r2, HeapNumber::kValueOffset);
6271 __ b(&left); 6254 __ b(&left);
6272 __ bind(&right_smi); 6255 __ bind(&right_smi);
6273 __ SmiUntag(r2, r0); // Can't clobber r0 yet. 6256 __ SmiToDouble(d1, r0);
6274 SwVfpRegister single_scratch = d2.low();
6275 __ vmov(single_scratch, r2);
6276 __ vcvt_f64_s32(d1, single_scratch);
6277 6257
6278 __ bind(&left); 6258 __ bind(&left);
6279 __ JumpIfSmi(r1, &left_smi); 6259 __ JumpIfSmi(r1, &left_smi);
6280 __ CheckMap(r1, r2, Heap::kHeapNumberMapRootIndex, &maybe_undefined2, 6260 __ CheckMap(r1, r2, Heap::kHeapNumberMapRootIndex, &maybe_undefined2,
6281 DONT_DO_SMI_CHECK); 6261 DONT_DO_SMI_CHECK);
6282 __ sub(r2, r1, Operand(kHeapObjectTag)); 6262 __ sub(r2, r1, Operand(kHeapObjectTag));
6283 __ vldr(d0, r2, HeapNumber::kValueOffset); 6263 __ vldr(d0, r2, HeapNumber::kValueOffset);
6284 __ b(&done); 6264 __ b(&done);
6285 __ bind(&left_smi); 6265 __ bind(&left_smi);
6286 __ SmiUntag(r2, r1); // Can't clobber r1 yet. 6266 __ SmiToDouble(d0, r1);
6287 single_scratch = d3.low();
6288 __ vmov(single_scratch, r2);
6289 __ vcvt_f64_s32(d0, single_scratch);
6290 6267
6291 __ bind(&done); 6268 __ bind(&done);
6292 // Compare operands. 6269 // Compare operands.
6293 __ VFPCompareAndSetFlags(d0, d1); 6270 __ VFPCompareAndSetFlags(d0, d1);
6294 6271
6295 // Don't base result on status bits when a NaN is involved. 6272 // Don't base result on status bits when a NaN is involved.
6296 __ b(vs, &unordered); 6273 __ b(vs, &unordered);
6297 6274
6298 // Return a result of -1, 0, or 1, based on status bits. 6275 // Return a result of -1, 0, or 1, based on status bits.
6299 __ mov(r0, Operand(EQUAL), LeaveCC, eq); 6276 __ mov(r0, Operand(EQUAL), LeaveCC, eq);
(...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after
6690 Register scratch2) { 6667 Register scratch2) {
6691 ASSERT(!elements.is(scratch1)); 6668 ASSERT(!elements.is(scratch1));
6692 ASSERT(!elements.is(scratch2)); 6669 ASSERT(!elements.is(scratch2));
6693 ASSERT(!name.is(scratch1)); 6670 ASSERT(!name.is(scratch1));
6694 ASSERT(!name.is(scratch2)); 6671 ASSERT(!name.is(scratch2));
6695 6672
6696 __ AssertName(name); 6673 __ AssertName(name);
6697 6674
6698 // Compute the capacity mask. 6675 // Compute the capacity mask.
6699 __ ldr(scratch1, FieldMemOperand(elements, kCapacityOffset)); 6676 __ ldr(scratch1, FieldMemOperand(elements, kCapacityOffset));
6700 __ mov(scratch1, Operand(scratch1, ASR, kSmiTagSize)); // convert smi to int 6677 __ SmiUntag(scratch1);
6701 __ sub(scratch1, scratch1, Operand(1)); 6678 __ sub(scratch1, scratch1, Operand(1));
6702 6679
6703 // Generate an unrolled loop that performs a few probes before 6680 // Generate an unrolled loop that performs a few probes before
6704 // giving up. Measurements done on Gmail indicate that 2 probes 6681 // giving up. Measurements done on Gmail indicate that 2 probes
6705 // cover ~93% of loads from dictionaries. 6682 // cover ~93% of loads from dictionaries.
6706 for (int i = 0; i < kInlinedProbes; i++) { 6683 for (int i = 0; i < kInlinedProbes; i++) {
6707 // Compute the masked index: (hash + i + i * i) & mask. 6684 // Compute the masked index: (hash + i + i * i) & mask.
6708 __ ldr(scratch2, FieldMemOperand(name, Name::kHashFieldOffset)); 6685 __ ldr(scratch2, FieldMemOperand(name, Name::kHashFieldOffset));
6709 if (i > 0) { 6686 if (i > 0) {
6710 // Add the probe offset (i + i * i) left shifted to avoid right shifting 6687 // Add the probe offset (i + i * i) left shifted to avoid right shifting
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
6771 Register key = r1; 6748 Register key = r1;
6772 Register index = r2; 6749 Register index = r2;
6773 Register mask = r3; 6750 Register mask = r3;
6774 Register hash = r4; 6751 Register hash = r4;
6775 Register undefined = r5; 6752 Register undefined = r5;
6776 Register entry_key = r6; 6753 Register entry_key = r6;
6777 6754
6778 Label in_dictionary, maybe_in_dictionary, not_in_dictionary; 6755 Label in_dictionary, maybe_in_dictionary, not_in_dictionary;
6779 6756
6780 __ ldr(mask, FieldMemOperand(dictionary, kCapacityOffset)); 6757 __ ldr(mask, FieldMemOperand(dictionary, kCapacityOffset));
6781 __ mov(mask, Operand(mask, ASR, kSmiTagSize)); 6758 __ SmiUntag(mask);
6782 __ sub(mask, mask, Operand(1)); 6759 __ sub(mask, mask, Operand(1));
6783 6760
6784 __ ldr(hash, FieldMemOperand(key, Name::kHashFieldOffset)); 6761 __ ldr(hash, FieldMemOperand(key, Name::kHashFieldOffset));
6785 6762
6786 __ LoadRoot(undefined, Heap::kUndefinedValueRootIndex); 6763 __ LoadRoot(undefined, Heap::kUndefinedValueRootIndex);
6787 6764
6788 for (int i = kInlinedProbes; i < kTotalProbes; i++) { 6765 for (int i = kInlinedProbes; i < kTotalProbes; i++) {
6789 // Compute the masked index: (hash + i + i * i) & mask. 6766 // Compute the masked index: (hash + i + i * i) & mask.
6790 // Capacity is smi 2^n. 6767 // Capacity is smi 2^n.
6791 if (i > 0) { 6768 if (i > 0) {
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after
7169 // call. 7146 // call.
7170 __ Push(r1, r3, r0); 7147 __ Push(r1, r3, r0);
7171 __ ldr(r5, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 7148 __ ldr(r5, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
7172 __ ldr(r5, FieldMemOperand(r5, JSFunction::kLiteralsOffset)); 7149 __ ldr(r5, FieldMemOperand(r5, JSFunction::kLiteralsOffset));
7173 __ Push(r5, r4); 7150 __ Push(r5, r4);
7174 __ TailCallRuntime(Runtime::kStoreArrayLiteralElement, 5, 1); 7151 __ TailCallRuntime(Runtime::kStoreArrayLiteralElement, 5, 1);
7175 7152
7176 // Array literal has ElementsKind of FAST_*_ELEMENTS and value is an object. 7153 // Array literal has ElementsKind of FAST_*_ELEMENTS and value is an object.
7177 __ bind(&fast_elements); 7154 __ bind(&fast_elements);
7178 __ ldr(r5, FieldMemOperand(r1, JSObject::kElementsOffset)); 7155 __ ldr(r5, FieldMemOperand(r1, JSObject::kElementsOffset));
7179 __ add(r6, r5, Operand(r3, LSL, kPointerSizeLog2 - kSmiTagSize)); 7156 __ add(r6, r5, Operand::PointerOffsetFromSmiKey(r3));
7180 __ add(r6, r6, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); 7157 __ add(r6, r6, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
7181 __ str(r0, MemOperand(r6, 0)); 7158 __ str(r0, MemOperand(r6, 0));
7182 // Update the write barrier for the array store. 7159 // Update the write barrier for the array store.
7183 __ RecordWrite(r5, r6, r0, kLRHasNotBeenSaved, kDontSaveFPRegs, 7160 __ RecordWrite(r5, r6, r0, kLRHasNotBeenSaved, kDontSaveFPRegs,
7184 EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); 7161 EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
7185 __ Ret(); 7162 __ Ret();
7186 7163
7187 // Array literal has ElementsKind of FAST_*_SMI_ELEMENTS or FAST_*_ELEMENTS, 7164 // Array literal has ElementsKind of FAST_*_SMI_ELEMENTS or FAST_*_ELEMENTS,
7188 // and value is Smi. 7165 // and value is Smi.
7189 __ bind(&smi_element); 7166 __ bind(&smi_element);
7190 __ ldr(r5, FieldMemOperand(r1, JSObject::kElementsOffset)); 7167 __ ldr(r5, FieldMemOperand(r1, JSObject::kElementsOffset));
7191 __ add(r6, r5, Operand(r3, LSL, kPointerSizeLog2 - kSmiTagSize)); 7168 __ add(r6, r5, Operand::PointerOffsetFromSmiKey(r3));
7192 __ str(r0, FieldMemOperand(r6, FixedArray::kHeaderSize)); 7169 __ str(r0, FieldMemOperand(r6, FixedArray::kHeaderSize));
7193 __ Ret(); 7170 __ Ret();
7194 7171
7195 // Array literal has ElementsKind of FAST_DOUBLE_ELEMENTS. 7172 // Array literal has ElementsKind of FAST_DOUBLE_ELEMENTS.
7196 __ bind(&double_elements); 7173 __ bind(&double_elements);
7197 __ ldr(r5, FieldMemOperand(r1, JSObject::kElementsOffset)); 7174 __ ldr(r5, FieldMemOperand(r1, JSObject::kElementsOffset));
7198 __ StoreNumberToDoubleElements(r0, r3, r5, r6, &slow_elements); 7175 __ StoreNumberToDoubleElements(r0, r3, r5, r6, &slow_elements);
7199 __ Ret(); 7176 __ Ret();
7200 } 7177 }
7201 7178
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after
7457 __ Jump(generic_construct_stub, RelocInfo::CODE_TARGET); 7434 __ Jump(generic_construct_stub, RelocInfo::CODE_TARGET);
7458 } 7435 }
7459 } 7436 }
7460 7437
7461 7438
7462 #undef __ 7439 #undef __
7463 7440
7464 } } // namespace v8::internal 7441 } } // namespace v8::internal
7465 7442
7466 #endif // V8_TARGET_ARCH_ARM 7443 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/builtins-arm.cc ('k') | src/arm/codegen-arm.cc » ('j') | src/arm/macro-assembler-arm.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698