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

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

Issue 6272019: ARM: Change BranchOnSmi/BranchOnNotSmi to JumpIfSmi/JumpIfNotSmi (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 9 years, 11 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
« no previous file with comments | « src/arm/builtins-arm.cc ('k') | src/arm/codegen-arm.cc » ('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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 434 matching lines...) Expand 10 before | Expand all | Expand 10 after
445 Register object, 445 Register object,
446 DwVfpRegister dst, 446 DwVfpRegister dst,
447 Register dst1, 447 Register dst1,
448 Register dst2, 448 Register dst2,
449 Register heap_number_map, 449 Register heap_number_map,
450 Register scratch1, 450 Register scratch1,
451 Register scratch2, 451 Register scratch2,
452 Label* not_number) { 452 Label* not_number) {
453 Label is_smi, done; 453 Label is_smi, done;
454 454
455 __ BranchOnSmi(object, &is_smi); 455 __ JumpIfSmi(object, &is_smi);
456 __ JumpIfNotHeapNumber(object, heap_number_map, scratch1, not_number); 456 __ JumpIfNotHeapNumber(object, heap_number_map, scratch1, not_number);
457 457
458 // Handle loading a double from a heap number. 458 // Handle loading a double from a heap number.
459 if (CpuFeatures::IsSupported(VFP3)) { 459 if (CpuFeatures::IsSupported(VFP3)) {
460 CpuFeatures::Scope scope(VFP3); 460 CpuFeatures::Scope scope(VFP3);
461 // Load the double from tagged HeapNumber to double register. 461 // Load the double from tagged HeapNumber to double register.
462 __ sub(scratch1, object, Operand(kHeapObjectTag)); 462 __ sub(scratch1, object, Operand(kHeapObjectTag));
463 __ vldr(dst, scratch1, HeapNumber::kValueOffset); 463 __ vldr(dst, scratch1, HeapNumber::kValueOffset);
464 } else { 464 } else {
465 ASSERT(destination == kCoreRegisters); 465 ASSERT(destination == kCoreRegisters);
(...skipping 511 matching lines...) Expand 10 before | Expand all | Expand 10 after
977 __ mov(mask, Operand(mask, ASR, kSmiTagSize + 1)); 977 __ mov(mask, Operand(mask, ASR, kSmiTagSize + 1));
978 __ sub(mask, mask, Operand(1)); // Make mask. 978 __ sub(mask, mask, Operand(1)); // Make mask.
979 979
980 // Calculate the entry in the number string cache. The hash value in the 980 // Calculate the entry in the number string cache. The hash value in the
981 // number string cache for smis is just the smi value, and the hash for 981 // number string cache for smis is just the smi value, and the hash for
982 // doubles is the xor of the upper and lower words. See 982 // doubles is the xor of the upper and lower words. See
983 // Heap::GetNumberStringCache. 983 // Heap::GetNumberStringCache.
984 Label is_smi; 984 Label is_smi;
985 Label load_result_from_cache; 985 Label load_result_from_cache;
986 if (!object_is_smi) { 986 if (!object_is_smi) {
987 __ BranchOnSmi(object, &is_smi); 987 __ JumpIfSmi(object, &is_smi);
988 if (CpuFeatures::IsSupported(VFP3)) { 988 if (CpuFeatures::IsSupported(VFP3)) {
989 CpuFeatures::Scope scope(VFP3); 989 CpuFeatures::Scope scope(VFP3);
990 __ CheckMap(object, 990 __ CheckMap(object,
991 scratch1, 991 scratch1,
992 Heap::kHeapNumberMapRootIndex, 992 Heap::kHeapNumberMapRootIndex,
993 not_found, 993 not_found,
994 true); 994 true);
995 995
996 STATIC_ASSERT(8 == kDoubleSize); 996 STATIC_ASSERT(8 == kDoubleSize);
997 __ add(scratch1, 997 __ add(scratch1,
998 object, 998 object,
999 Operand(HeapNumber::kValueOffset - kHeapObjectTag)); 999 Operand(HeapNumber::kValueOffset - kHeapObjectTag));
1000 __ ldm(ia, scratch1, scratch1.bit() | scratch2.bit()); 1000 __ ldm(ia, scratch1, scratch1.bit() | scratch2.bit());
1001 __ eor(scratch1, scratch1, Operand(scratch2)); 1001 __ eor(scratch1, scratch1, Operand(scratch2));
1002 __ and_(scratch1, scratch1, Operand(mask)); 1002 __ and_(scratch1, scratch1, Operand(mask));
1003 1003
1004 // Calculate address of entry in string cache: each entry consists 1004 // Calculate address of entry in string cache: each entry consists
1005 // of two pointer sized fields. 1005 // of two pointer sized fields.
1006 __ add(scratch1, 1006 __ add(scratch1,
1007 number_string_cache, 1007 number_string_cache,
1008 Operand(scratch1, LSL, kPointerSizeLog2 + 1)); 1008 Operand(scratch1, LSL, kPointerSizeLog2 + 1));
1009 1009
1010 Register probe = mask; 1010 Register probe = mask;
1011 __ ldr(probe, 1011 __ ldr(probe,
1012 FieldMemOperand(scratch1, FixedArray::kHeaderSize)); 1012 FieldMemOperand(scratch1, FixedArray::kHeaderSize));
1013 __ BranchOnSmi(probe, not_found); 1013 __ JumpIfSmi(probe, not_found);
1014 __ sub(scratch2, object, Operand(kHeapObjectTag)); 1014 __ sub(scratch2, object, Operand(kHeapObjectTag));
1015 __ vldr(d0, scratch2, HeapNumber::kValueOffset); 1015 __ vldr(d0, scratch2, HeapNumber::kValueOffset);
1016 __ sub(probe, probe, Operand(kHeapObjectTag)); 1016 __ sub(probe, probe, Operand(kHeapObjectTag));
1017 __ vldr(d1, probe, HeapNumber::kValueOffset); 1017 __ vldr(d1, probe, HeapNumber::kValueOffset);
1018 __ VFPCompareAndSetFlags(d0, d1); 1018 __ VFPCompareAndSetFlags(d0, d1);
1019 __ b(ne, not_found); // The cache did not contain this value. 1019 __ b(ne, not_found); // The cache did not contain this value.
1020 __ b(&load_result_from_cache); 1020 __ b(&load_result_from_cache);
1021 } else { 1021 } else {
1022 __ b(not_found); 1022 __ b(not_found);
1023 } 1023 }
(...skipping 1078 matching lines...) Expand 10 before | Expand all | Expand 10 after
2102 } 2102 }
2103 HandleBinaryOpSlowCases(masm, &not_smi, lhs, rhs, Builtins::MUL); 2103 HandleBinaryOpSlowCases(masm, &not_smi, lhs, rhs, Builtins::MUL);
2104 break; 2104 break;
2105 } 2105 }
2106 2106
2107 case Token::DIV: 2107 case Token::DIV:
2108 case Token::MOD: { 2108 case Token::MOD: {
2109 Label not_smi; 2109 Label not_smi;
2110 if (ShouldGenerateSmiCode() && specialized_on_rhs_) { 2110 if (ShouldGenerateSmiCode() && specialized_on_rhs_) {
2111 Label lhs_is_unsuitable; 2111 Label lhs_is_unsuitable;
2112 __ BranchOnNotSmi(lhs, &not_smi); 2112 __ JumpIfNotSmi(lhs, &not_smi);
2113 if (IsPowerOf2(constant_rhs_)) { 2113 if (IsPowerOf2(constant_rhs_)) {
2114 if (op_ == Token::MOD) { 2114 if (op_ == Token::MOD) {
2115 __ and_(rhs, 2115 __ and_(rhs,
2116 lhs, 2116 lhs,
2117 Operand(0x80000000u | ((constant_rhs_ << kSmiTagSize) - 1)), 2117 Operand(0x80000000u | ((constant_rhs_ << kSmiTagSize) - 1)),
2118 SetCC); 2118 SetCC);
2119 // We now have the answer, but if the input was negative we also 2119 // We now have the answer, but if the input was negative we also
2120 // have the sign bit. Our work is done if the result is 2120 // have the sign bit. Our work is done if the result is
2121 // positive or zero: 2121 // positive or zero:
2122 if (!rhs.is(r0)) { 2122 if (!rhs.is(r0)) {
(...skipping 545 matching lines...) Expand 10 before | Expand all | Expand 10 after
2668 __ TailCallStub(&stub); 2668 __ TailCallStub(&stub);
2669 } 2669 }
2670 2670
2671 2671
2672 void TypeRecordingBinaryOpStub::GenerateAddStrings(MacroAssembler* masm) { 2672 void TypeRecordingBinaryOpStub::GenerateAddStrings(MacroAssembler* masm) {
2673 Register left = r1; 2673 Register left = r1;
2674 Register right = r0; 2674 Register right = r0;
2675 Label call_runtime; 2675 Label call_runtime;
2676 2676
2677 // Check if first argument is a string. 2677 // Check if first argument is a string.
2678 __ BranchOnSmi(left, &call_runtime); 2678 __ JumpIfSmi(left, &call_runtime);
2679 __ CompareObjectType(left, r2, r2, FIRST_NONSTRING_TYPE); 2679 __ CompareObjectType(left, r2, r2, FIRST_NONSTRING_TYPE);
2680 __ b(ge, &call_runtime); 2680 __ b(ge, &call_runtime);
2681 2681
2682 // First argument is a a string, test second. 2682 // First argument is a a string, test second.
2683 __ BranchOnSmi(right, &call_runtime); 2683 __ JumpIfSmi(right, &call_runtime);
2684 __ CompareObjectType(right, r2, r2, FIRST_NONSTRING_TYPE); 2684 __ CompareObjectType(right, r2, r2, FIRST_NONSTRING_TYPE);
2685 __ b(ge, &call_runtime); 2685 __ b(ge, &call_runtime);
2686 2686
2687 // First and second argument are strings. 2687 // First and second argument are strings.
2688 StringAddStub string_add_stub(NO_STRING_CHECK_IN_STUB); 2688 StringAddStub string_add_stub(NO_STRING_CHECK_IN_STUB);
2689 GenerateRegisterArgsPush(masm); 2689 GenerateRegisterArgsPush(masm);
2690 __ TailCallStub(&string_add_stub); 2690 __ TailCallStub(&string_add_stub);
2691 2691
2692 // At least one argument is not a string. 2692 // At least one argument is not a string.
2693 __ bind(&call_runtime); 2693 __ bind(&call_runtime);
(...skipping 22 matching lines...) Expand all
2716 2716
2717 // Code below will scratch result if allocation fails. To keep both arguments 2717 // Code below will scratch result if allocation fails. To keep both arguments
2718 // intact for the runtime call result cannot be one of these. 2718 // intact for the runtime call result cannot be one of these.
2719 ASSERT(!result.is(r0) && !result.is(r1)); 2719 ASSERT(!result.is(r0) && !result.is(r1));
2720 2720
2721 if (mode_ == OVERWRITE_LEFT || mode_ == OVERWRITE_RIGHT) { 2721 if (mode_ == OVERWRITE_LEFT || mode_ == OVERWRITE_RIGHT) {
2722 Label skip_allocation, allocated; 2722 Label skip_allocation, allocated;
2723 Register overwritable_operand = mode_ == OVERWRITE_LEFT ? r1 : r0; 2723 Register overwritable_operand = mode_ == OVERWRITE_LEFT ? r1 : r0;
2724 // If the overwritable operand is already an object, we skip the 2724 // If the overwritable operand is already an object, we skip the
2725 // allocation of a heap number. 2725 // allocation of a heap number.
2726 __ BranchOnNotSmi(overwritable_operand, &skip_allocation); 2726 __ JumpIfNotSmi(overwritable_operand, &skip_allocation);
2727 // Allocate a heap number for the result. 2727 // Allocate a heap number for the result.
2728 __ AllocateHeapNumber( 2728 __ AllocateHeapNumber(
2729 result, scratch1, scratch2, heap_number_map, gc_required); 2729 result, scratch1, scratch2, heap_number_map, gc_required);
2730 __ b(&allocated); 2730 __ b(&allocated);
2731 __ bind(&skip_allocation); 2731 __ bind(&skip_allocation);
2732 // Use object holding the overwritable operand for result. 2732 // Use object holding the overwritable operand for result.
2733 __ mov(result, Operand(overwritable_operand)); 2733 __ mov(result, Operand(overwritable_operand));
2734 __ bind(&allocated); 2734 __ bind(&allocated);
2735 } else { 2735 } else {
2736 ASSERT(mode_ == NO_OVERWRITE); 2736 ASSERT(mode_ == NO_OVERWRITE);
2737 __ AllocateHeapNumber( 2737 __ AllocateHeapNumber(
2738 result, scratch1, scratch2, heap_number_map, gc_required); 2738 result, scratch1, scratch2, heap_number_map, gc_required);
2739 } 2739 }
2740 } 2740 }
2741 2741
2742 2742
2743 void TypeRecordingBinaryOpStub::GenerateRegisterArgsPush(MacroAssembler* masm) { 2743 void TypeRecordingBinaryOpStub::GenerateRegisterArgsPush(MacroAssembler* masm) {
2744 __ Push(r1, r0); 2744 __ Push(r1, r0);
2745 } 2745 }
2746 2746
2747 2747
2748 void TranscendentalCacheStub::Generate(MacroAssembler* masm) { 2748 void TranscendentalCacheStub::Generate(MacroAssembler* masm) {
2749 // Argument is a number and is on stack and in r0. 2749 // Argument is a number and is on stack and in r0.
2750 Label runtime_call; 2750 Label runtime_call;
2751 Label input_not_smi; 2751 Label input_not_smi;
2752 Label loaded; 2752 Label loaded;
2753 2753
2754 if (CpuFeatures::IsSupported(VFP3)) { 2754 if (CpuFeatures::IsSupported(VFP3)) {
2755 // Load argument and check if it is a smi. 2755 // Load argument and check if it is a smi.
2756 __ BranchOnNotSmi(r0, &input_not_smi); 2756 __ JumpIfNotSmi(r0, &input_not_smi);
2757 2757
2758 CpuFeatures::Scope scope(VFP3); 2758 CpuFeatures::Scope scope(VFP3);
2759 // Input is a smi. Convert to double and load the low and high words 2759 // Input is a smi. Convert to double and load the low and high words
2760 // of the double into r2, r3. 2760 // of the double into r2, r3.
2761 __ IntegerToDoubleConversionWithVFP3(r0, r3, r2); 2761 __ IntegerToDoubleConversionWithVFP3(r0, r3, r2);
2762 __ b(&loaded); 2762 __ b(&loaded);
2763 2763
2764 __ bind(&input_not_smi); 2764 __ bind(&input_not_smi);
2765 // Check if input is a HeapNumber. 2765 // Check if input is a HeapNumber.
2766 __ CheckMap(r0, 2766 __ CheckMap(r0,
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
2900 __ ldr(r3, FieldMemOperand(r0, HeapNumber::kMantissaOffset)); 2900 __ ldr(r3, FieldMemOperand(r0, HeapNumber::kMantissaOffset));
2901 __ ldr(r2, FieldMemOperand(r0, HeapNumber::kExponentOffset)); 2901 __ ldr(r2, FieldMemOperand(r0, HeapNumber::kExponentOffset));
2902 __ str(r3, FieldMemOperand(r1, HeapNumber::kMantissaOffset)); 2902 __ str(r3, FieldMemOperand(r1, HeapNumber::kMantissaOffset));
2903 __ eor(r2, r2, Operand(HeapNumber::kSignMask)); // Flip sign. 2903 __ eor(r2, r2, Operand(HeapNumber::kSignMask)); // Flip sign.
2904 __ str(r2, FieldMemOperand(r1, HeapNumber::kExponentOffset)); 2904 __ str(r2, FieldMemOperand(r1, HeapNumber::kExponentOffset));
2905 __ mov(r0, Operand(r1)); 2905 __ mov(r0, Operand(r1));
2906 } 2906 }
2907 } else if (op_ == Token::BIT_NOT) { 2907 } else if (op_ == Token::BIT_NOT) {
2908 if (include_smi_code_) { 2908 if (include_smi_code_) {
2909 Label non_smi; 2909 Label non_smi;
2910 __ BranchOnNotSmi(r0, &non_smi); 2910 __ JumpIfNotSmi(r0, &non_smi);
2911 __ mvn(r0, Operand(r0)); 2911 __ mvn(r0, Operand(r0));
2912 // Bit-clear inverted smi-tag. 2912 // Bit-clear inverted smi-tag.
2913 __ bic(r0, r0, Operand(kSmiTagMask)); 2913 __ bic(r0, r0, Operand(kSmiTagMask));
2914 __ Ret(); 2914 __ Ret();
2915 __ bind(&non_smi); 2915 __ bind(&non_smi);
2916 } else if (FLAG_debug_code) { 2916 } else if (FLAG_debug_code) {
2917 __ tst(r0, Operand(kSmiTagMask)); 2917 __ tst(r0, Operand(kSmiTagMask));
2918 __ Assert(ne, "Unexpected smi operand."); 2918 __ Assert(ne, "Unexpected smi operand.");
2919 } 2919 }
2920 2920
(...skipping 508 matching lines...) Expand 10 before | Expand all | Expand 10 after
3429 const int32_t kDeltaToLoadBoolResult = 3 * kPointerSize; 3429 const int32_t kDeltaToLoadBoolResult = 3 * kPointerSize;
3430 3430
3431 Label slow, loop, is_instance, is_not_instance, not_js_object; 3431 Label slow, loop, is_instance, is_not_instance, not_js_object;
3432 3432
3433 if (!HasArgsInRegisters()) { 3433 if (!HasArgsInRegisters()) {
3434 __ ldr(object, MemOperand(sp, 1 * kPointerSize)); 3434 __ ldr(object, MemOperand(sp, 1 * kPointerSize));
3435 __ ldr(function, MemOperand(sp, 0)); 3435 __ ldr(function, MemOperand(sp, 0));
3436 } 3436 }
3437 3437
3438 // Check that the left hand is a JS object and load map. 3438 // Check that the left hand is a JS object and load map.
3439 __ BranchOnSmi(object, &not_js_object); 3439 __ JumpIfSmi(object, &not_js_object);
3440 __ IsObjectJSObjectType(object, map, scratch, &not_js_object); 3440 __ IsObjectJSObjectType(object, map, scratch, &not_js_object);
3441 3441
3442 // If there is a call site cache don't look in the global cache, but do the 3442 // If there is a call site cache don't look in the global cache, but do the
3443 // real lookup and update the call site cache. 3443 // real lookup and update the call site cache.
3444 if (!HasCallSiteInlineCheck()) { 3444 if (!HasCallSiteInlineCheck()) {
3445 Label miss; 3445 Label miss;
3446 __ LoadRoot(ip, Heap::kInstanceofCacheFunctionRootIndex); 3446 __ LoadRoot(ip, Heap::kInstanceofCacheFunctionRootIndex);
3447 __ cmp(function, ip); 3447 __ cmp(function, ip);
3448 __ b(ne, &miss); 3448 __ b(ne, &miss);
3449 __ LoadRoot(ip, Heap::kInstanceofCacheMapRootIndex); 3449 __ LoadRoot(ip, Heap::kInstanceofCacheMapRootIndex);
3450 __ cmp(map, ip); 3450 __ cmp(map, ip);
3451 __ b(ne, &miss); 3451 __ b(ne, &miss);
3452 __ LoadRoot(r0, Heap::kInstanceofCacheAnswerRootIndex); 3452 __ LoadRoot(r0, Heap::kInstanceofCacheAnswerRootIndex);
3453 __ Ret(HasArgsInRegisters() ? 0 : 2); 3453 __ Ret(HasArgsInRegisters() ? 0 : 2);
3454 3454
3455 __ bind(&miss); 3455 __ bind(&miss);
3456 } 3456 }
3457 3457
3458 // Get the prototype of the function. 3458 // Get the prototype of the function.
3459 __ TryGetFunctionPrototype(function, prototype, scratch, &slow); 3459 __ TryGetFunctionPrototype(function, prototype, scratch, &slow);
3460 3460
3461 // Check that the function prototype is a JS object. 3461 // Check that the function prototype is a JS object.
3462 __ BranchOnSmi(prototype, &slow); 3462 __ JumpIfSmi(prototype, &slow);
3463 __ IsObjectJSObjectType(prototype, scratch, scratch, &slow); 3463 __ IsObjectJSObjectType(prototype, scratch, scratch, &slow);
3464 3464
3465 // Update the global instanceof or call site inlined cache with the current 3465 // Update the global instanceof or call site inlined cache with the current
3466 // map and function. The cached answer will be set when it is known below. 3466 // map and function. The cached answer will be set when it is known below.
3467 if (!HasCallSiteInlineCheck()) { 3467 if (!HasCallSiteInlineCheck()) {
3468 __ StoreRoot(function, Heap::kInstanceofCacheFunctionRootIndex); 3468 __ StoreRoot(function, Heap::kInstanceofCacheFunctionRootIndex);
3469 __ StoreRoot(map, Heap::kInstanceofCacheMapRootIndex); 3469 __ StoreRoot(map, Heap::kInstanceofCacheMapRootIndex);
3470 } else { 3470 } else {
3471 ASSERT(HasArgsInRegisters()); 3471 ASSERT(HasArgsInRegisters());
3472 // Patch the (relocated) inlined map check. 3472 // Patch the (relocated) inlined map check.
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
3532 if (!ReturnTrueFalseObject()) { 3532 if (!ReturnTrueFalseObject()) {
3533 __ mov(r0, Operand(Smi::FromInt(1))); 3533 __ mov(r0, Operand(Smi::FromInt(1)));
3534 } 3534 }
3535 } 3535 }
3536 __ Ret(HasArgsInRegisters() ? 0 : 2); 3536 __ Ret(HasArgsInRegisters() ? 0 : 2);
3537 3537
3538 Label object_not_null, object_not_null_or_smi; 3538 Label object_not_null, object_not_null_or_smi;
3539 __ bind(&not_js_object); 3539 __ bind(&not_js_object);
3540 // Before null, smi and string value checks, check that the rhs is a function 3540 // Before null, smi and string value checks, check that the rhs is a function
3541 // as for a non-function rhs an exception needs to be thrown. 3541 // as for a non-function rhs an exception needs to be thrown.
3542 __ BranchOnSmi(function, &slow); 3542 __ JumpIfSmi(function, &slow);
3543 __ CompareObjectType(function, scratch2, scratch, JS_FUNCTION_TYPE); 3543 __ CompareObjectType(function, scratch2, scratch, JS_FUNCTION_TYPE);
3544 __ b(ne, &slow); 3544 __ b(ne, &slow);
3545 3545
3546 // Null is not instance of anything. 3546 // Null is not instance of anything.
3547 __ cmp(scratch, Operand(Factory::null_value())); 3547 __ cmp(scratch, Operand(Factory::null_value()));
3548 __ b(ne, &object_not_null); 3548 __ b(ne, &object_not_null);
3549 __ mov(r0, Operand(Smi::FromInt(1))); 3549 __ mov(r0, Operand(Smi::FromInt(1)));
3550 __ Ret(HasArgsInRegisters() ? 0 : 2); 3550 __ Ret(HasArgsInRegisters() ? 0 : 2);
3551 3551
3552 __ bind(&object_not_null); 3552 __ bind(&object_not_null);
3553 // Smi values are not instances of anything. 3553 // Smi values are not instances of anything.
3554 __ BranchOnNotSmi(object, &object_not_null_or_smi); 3554 __ JumpIfNotSmi(object, &object_not_null_or_smi);
3555 __ mov(r0, Operand(Smi::FromInt(1))); 3555 __ mov(r0, Operand(Smi::FromInt(1)));
3556 __ Ret(HasArgsInRegisters() ? 0 : 2); 3556 __ Ret(HasArgsInRegisters() ? 0 : 2);
3557 3557
3558 __ bind(&object_not_null_or_smi); 3558 __ bind(&object_not_null_or_smi);
3559 // String values are not instances of anything. 3559 // String values are not instances of anything.
3560 __ IsObjectJSStringType(object, scratch, &slow); 3560 __ IsObjectJSStringType(object, scratch, &slow);
3561 __ mov(r0, Operand(Smi::FromInt(1))); 3561 __ mov(r0, Operand(Smi::FromInt(1)));
3562 __ Ret(HasArgsInRegisters() ? 0 : 2); 3562 __ Ret(HasArgsInRegisters() ? 0 : 2);
3563 3563
3564 // Slow-case. Tail call builtin. 3564 // Slow-case. Tail call builtin.
(...skipping 23 matching lines...) Expand all
3588 3588
3589 3589
3590 void ArgumentsAccessStub::GenerateReadElement(MacroAssembler* masm) { 3590 void ArgumentsAccessStub::GenerateReadElement(MacroAssembler* masm) {
3591 // The displacement is the offset of the last parameter (if any) 3591 // The displacement is the offset of the last parameter (if any)
3592 // relative to the frame pointer. 3592 // relative to the frame pointer.
3593 static const int kDisplacement = 3593 static const int kDisplacement =
3594 StandardFrameConstants::kCallerSPOffset - kPointerSize; 3594 StandardFrameConstants::kCallerSPOffset - kPointerSize;
3595 3595
3596 // Check that the key is a smi. 3596 // Check that the key is a smi.
3597 Label slow; 3597 Label slow;
3598 __ BranchOnNotSmi(r1, &slow); 3598 __ JumpIfNotSmi(r1, &slow);
3599 3599
3600 // Check if the calling frame is an arguments adaptor frame. 3600 // Check if the calling frame is an arguments adaptor frame.
3601 Label adaptor; 3601 Label adaptor;
3602 __ ldr(r2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); 3602 __ ldr(r2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
3603 __ ldr(r3, MemOperand(r2, StandardFrameConstants::kContextOffset)); 3603 __ ldr(r3, MemOperand(r2, StandardFrameConstants::kContextOffset));
3604 __ cmp(r3, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); 3604 __ cmp(r3, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
3605 __ b(eq, &adaptor); 3605 __ b(eq, &adaptor);
3606 3606
3607 // Check index against formal parameters count limit passed in 3607 // Check index against formal parameters count limit passed in
3608 // through register r0. Use unsigned comparison to get negative 3608 // through register r0. Use unsigned comparison to get negative
(...skipping 561 matching lines...) Expand 10 before | Expand all | Expand 10 after
4170 4170
4171 // If the receiver might be a value (string, number or boolean) check for this 4171 // If the receiver might be a value (string, number or boolean) check for this
4172 // and box it if it is. 4172 // and box it if it is.
4173 if (ReceiverMightBeValue()) { 4173 if (ReceiverMightBeValue()) {
4174 // Get the receiver from the stack. 4174 // Get the receiver from the stack.
4175 // function, receiver [, arguments] 4175 // function, receiver [, arguments]
4176 Label receiver_is_value, receiver_is_js_object; 4176 Label receiver_is_value, receiver_is_js_object;
4177 __ ldr(r1, MemOperand(sp, argc_ * kPointerSize)); 4177 __ ldr(r1, MemOperand(sp, argc_ * kPointerSize));
4178 4178
4179 // Check if receiver is a smi (which is a number value). 4179 // Check if receiver is a smi (which is a number value).
4180 __ BranchOnSmi(r1, &receiver_is_value); 4180 __ JumpIfSmi(r1, &receiver_is_value);
4181 4181
4182 // Check if the receiver is a valid JS object. 4182 // Check if the receiver is a valid JS object.
4183 __ CompareObjectType(r1, r2, r2, FIRST_JS_OBJECT_TYPE); 4183 __ CompareObjectType(r1, r2, r2, FIRST_JS_OBJECT_TYPE);
4184 __ b(ge, &receiver_is_js_object); 4184 __ b(ge, &receiver_is_js_object);
4185 4185
4186 // Call the runtime to box the value. 4186 // Call the runtime to box the value.
4187 __ bind(&receiver_is_value); 4187 __ bind(&receiver_is_value);
4188 __ EnterInternalFrame(); 4188 __ EnterInternalFrame();
4189 __ push(r1); 4189 __ push(r1);
4190 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_JS); 4190 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_JS);
4191 __ LeaveInternalFrame(); 4191 __ LeaveInternalFrame();
4192 __ str(r0, MemOperand(sp, argc_ * kPointerSize)); 4192 __ str(r0, MemOperand(sp, argc_ * kPointerSize));
4193 4193
4194 __ bind(&receiver_is_js_object); 4194 __ bind(&receiver_is_js_object);
4195 } 4195 }
4196 4196
4197 // Get the function to call from the stack. 4197 // Get the function to call from the stack.
4198 // function, receiver [, arguments] 4198 // function, receiver [, arguments]
4199 __ ldr(r1, MemOperand(sp, (argc_ + 1) * kPointerSize)); 4199 __ ldr(r1, MemOperand(sp, (argc_ + 1) * kPointerSize));
4200 4200
4201 // Check that the function is really a JavaScript function. 4201 // Check that the function is really a JavaScript function.
4202 // r1: pushed function (to be verified) 4202 // r1: pushed function (to be verified)
4203 __ BranchOnSmi(r1, &slow); 4203 __ JumpIfSmi(r1, &slow);
4204 // Get the map of the function object. 4204 // Get the map of the function object.
4205 __ CompareObjectType(r1, r2, r2, JS_FUNCTION_TYPE); 4205 __ CompareObjectType(r1, r2, r2, JS_FUNCTION_TYPE);
4206 __ b(ne, &slow); 4206 __ b(ne, &slow);
4207 4207
4208 // Fast-case: Invoke the function now. 4208 // Fast-case: Invoke the function now.
4209 // r1: pushed function 4209 // r1: pushed function
4210 ParameterCount actual(argc_); 4210 ParameterCount actual(argc_);
4211 __ InvokeFunction(r1, actual, JUMP_FUNCTION); 4211 __ InvokeFunction(r1, actual, JUMP_FUNCTION);
4212 4212
4213 // Slow-case: Non-function called. 4213 // Slow-case: Non-function called.
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
4297 } 4297 }
4298 4298
4299 4299
4300 // StringCharCodeAtGenerator 4300 // StringCharCodeAtGenerator
4301 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) { 4301 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) {
4302 Label flat_string; 4302 Label flat_string;
4303 Label ascii_string; 4303 Label ascii_string;
4304 Label got_char_code; 4304 Label got_char_code;
4305 4305
4306 // If the receiver is a smi trigger the non-string case. 4306 // If the receiver is a smi trigger the non-string case.
4307 __ BranchOnSmi(object_, receiver_not_string_); 4307 __ JumpIfSmi(object_, receiver_not_string_);
4308 4308
4309 // Fetch the instance type of the receiver into result register. 4309 // Fetch the instance type of the receiver into result register.
4310 __ ldr(result_, FieldMemOperand(object_, HeapObject::kMapOffset)); 4310 __ ldr(result_, FieldMemOperand(object_, HeapObject::kMapOffset));
4311 __ ldrb(result_, FieldMemOperand(result_, Map::kInstanceTypeOffset)); 4311 __ ldrb(result_, FieldMemOperand(result_, Map::kInstanceTypeOffset));
4312 // If the receiver is not a string trigger the non-string case. 4312 // If the receiver is not a string trigger the non-string case.
4313 __ tst(result_, Operand(kIsNotStringMask)); 4313 __ tst(result_, Operand(kIsNotStringMask));
4314 __ b(ne, receiver_not_string_); 4314 __ b(ne, receiver_not_string_);
4315 4315
4316 // If the index is non-smi trigger the non-smi case. 4316 // If the index is non-smi trigger the non-smi case.
4317 __ BranchOnNotSmi(index_, &index_not_smi_); 4317 __ JumpIfNotSmi(index_, &index_not_smi_);
4318 4318
4319 // Put smi-tagged index into scratch register. 4319 // Put smi-tagged index into scratch register.
4320 __ mov(scratch_, index_); 4320 __ mov(scratch_, index_);
4321 __ bind(&got_smi_index_); 4321 __ bind(&got_smi_index_);
4322 4322
4323 // Check for index out of range. 4323 // Check for index out of range.
4324 __ ldr(ip, FieldMemOperand(object_, String::kLengthOffset)); 4324 __ ldr(ip, FieldMemOperand(object_, String::kLengthOffset));
4325 __ cmp(ip, Operand(scratch_)); 4325 __ cmp(ip, Operand(scratch_));
4326 __ b(ls, index_out_of_range_); 4326 __ b(ls, index_out_of_range_);
4327 4327
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
4404 // Save the conversion result before the pop instructions below 4404 // Save the conversion result before the pop instructions below
4405 // have a chance to overwrite it. 4405 // have a chance to overwrite it.
4406 __ Move(scratch_, r0); 4406 __ Move(scratch_, r0);
4407 __ pop(index_); 4407 __ pop(index_);
4408 __ pop(object_); 4408 __ pop(object_);
4409 // Reload the instance type. 4409 // Reload the instance type.
4410 __ ldr(result_, FieldMemOperand(object_, HeapObject::kMapOffset)); 4410 __ ldr(result_, FieldMemOperand(object_, HeapObject::kMapOffset));
4411 __ ldrb(result_, FieldMemOperand(result_, Map::kInstanceTypeOffset)); 4411 __ ldrb(result_, FieldMemOperand(result_, Map::kInstanceTypeOffset));
4412 call_helper.AfterCall(masm); 4412 call_helper.AfterCall(masm);
4413 // If index is still not a smi, it must be out of range. 4413 // If index is still not a smi, it must be out of range.
4414 __ BranchOnNotSmi(scratch_, index_out_of_range_); 4414 __ JumpIfNotSmi(scratch_, index_out_of_range_);
4415 // Otherwise, return to the fast path. 4415 // Otherwise, return to the fast path.
4416 __ jmp(&got_smi_index_); 4416 __ jmp(&got_smi_index_);
4417 4417
4418 // Call runtime. We get here when the receiver is a string and the 4418 // Call runtime. We get here when the receiver is a string and the
4419 // index is a number, but the code of getting the actual character 4419 // index is a number, but the code of getting the actual character
4420 // is too complex (e.g., when the string needs to be flattened). 4420 // is too complex (e.g., when the string needs to be flattened).
4421 __ bind(&call_runtime_); 4421 __ bind(&call_runtime_);
4422 call_helper.BeforeCall(masm); 4422 call_helper.BeforeCall(masm);
4423 __ Push(object_, index_); 4423 __ Push(object_, index_);
4424 __ CallRuntime(Runtime::kStringCharCodeAt, 2); 4424 __ CallRuntime(Runtime::kStringCharCodeAt, 2);
(...skipping 1195 matching lines...) Expand 10 before | Expand all | Expand 10 after
5620 __ pop(r1); 5620 __ pop(r1);
5621 __ Jump(r2); 5621 __ Jump(r2);
5622 } 5622 }
5623 5623
5624 5624
5625 #undef __ 5625 #undef __
5626 5626
5627 } } // namespace v8::internal 5627 } } // namespace v8::internal
5628 5628
5629 #endif // V8_TARGET_ARCH_ARM 5629 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/builtins-arm.cc ('k') | src/arm/codegen-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698