OLD | NEW |
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 1611 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1622 __ push(r0); // Save result on stack | 1622 __ push(r0); // Save result on stack |
1623 result_saved = true; | 1623 result_saved = true; |
1624 } | 1624 } |
1625 switch (property->kind()) { | 1625 switch (property->kind()) { |
1626 case ObjectLiteral::Property::CONSTANT: | 1626 case ObjectLiteral::Property::CONSTANT: |
1627 UNREACHABLE(); | 1627 UNREACHABLE(); |
1628 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1628 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
1629 ASSERT(!CompileTimeValue::IsCompileTimeValue(property->value())); | 1629 ASSERT(!CompileTimeValue::IsCompileTimeValue(property->value())); |
1630 // Fall through. | 1630 // Fall through. |
1631 case ObjectLiteral::Property::COMPUTED: | 1631 case ObjectLiteral::Property::COMPUTED: |
1632 if (key->handle()->IsSymbol()) { | 1632 if (key->handle()->IsInternalizedString()) { |
1633 if (property->emit_store()) { | 1633 if (property->emit_store()) { |
1634 VisitForAccumulatorValue(value); | 1634 VisitForAccumulatorValue(value); |
1635 __ mov(r2, Operand(key->handle())); | 1635 __ mov(r2, Operand(key->handle())); |
1636 __ ldr(r1, MemOperand(sp)); | 1636 __ ldr(r1, MemOperand(sp)); |
1637 Handle<Code> ic = is_classic_mode() | 1637 Handle<Code> ic = is_classic_mode() |
1638 ? isolate()->builtins()->StoreIC_Initialize() | 1638 ? isolate()->builtins()->StoreIC_Initialize() |
1639 : isolate()->builtins()->StoreIC_Initialize_Strict(); | 1639 : isolate()->builtins()->StoreIC_Initialize_Strict(); |
1640 CallIC(ic, RelocInfo::CODE_TARGET, key->LiteralFeedbackId()); | 1640 CallIC(ic, RelocInfo::CODE_TARGET, key->LiteralFeedbackId()); |
1641 PrepareForBailoutForId(key->id(), NO_REGISTERS); | 1641 PrepareForBailoutForId(key->id(), NO_REGISTERS); |
1642 } else { | 1642 } else { |
(...skipping 1039 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2682 __ tst(ip, Operand(1 << Map::kStringWrapperSafeForDefaultValueOf)); | 2682 __ tst(ip, Operand(1 << Map::kStringWrapperSafeForDefaultValueOf)); |
2683 __ b(ne, if_true); | 2683 __ b(ne, if_true); |
2684 | 2684 |
2685 // Check for fast case object. Generate false result for slow case object. | 2685 // Check for fast case object. Generate false result for slow case object. |
2686 __ ldr(r2, FieldMemOperand(r0, JSObject::kPropertiesOffset)); | 2686 __ ldr(r2, FieldMemOperand(r0, JSObject::kPropertiesOffset)); |
2687 __ ldr(r2, FieldMemOperand(r2, HeapObject::kMapOffset)); | 2687 __ ldr(r2, FieldMemOperand(r2, HeapObject::kMapOffset)); |
2688 __ LoadRoot(ip, Heap::kHashTableMapRootIndex); | 2688 __ LoadRoot(ip, Heap::kHashTableMapRootIndex); |
2689 __ cmp(r2, ip); | 2689 __ cmp(r2, ip); |
2690 __ b(eq, if_false); | 2690 __ b(eq, if_false); |
2691 | 2691 |
2692 // Look for valueOf symbol in the descriptor array, and indicate false if | 2692 // Look for valueOf name in the descriptor array, and indicate false if |
2693 // found. Since we omit an enumeration index check, if it is added via a | 2693 // found. Since we omit an enumeration index check, if it is added via a |
2694 // transition that shares its descriptor array, this is a false positive. | 2694 // transition that shares its descriptor array, this is a false positive. |
2695 Label entry, loop, done; | 2695 Label entry, loop, done; |
2696 | 2696 |
2697 // Skip loop if no descriptors are valid. | 2697 // Skip loop if no descriptors are valid. |
2698 __ NumberOfOwnDescriptors(r3, r1); | 2698 __ NumberOfOwnDescriptors(r3, r1); |
2699 __ cmp(r3, Operand::Zero()); | 2699 __ cmp(r3, Operand::Zero()); |
2700 __ b(eq, &done); | 2700 __ b(eq, &done); |
2701 | 2701 |
2702 __ LoadInstanceDescriptors(r1, r4); | 2702 __ LoadInstanceDescriptors(r1, r4); |
2703 // r4: descriptor array. | 2703 // r4: descriptor array. |
2704 // r3: valid entries in the descriptor array. | 2704 // r3: valid entries in the descriptor array. |
2705 STATIC_ASSERT(kSmiTag == 0); | 2705 STATIC_ASSERT(kSmiTag == 0); |
2706 STATIC_ASSERT(kSmiTagSize == 1); | 2706 STATIC_ASSERT(kSmiTagSize == 1); |
2707 STATIC_ASSERT(kPointerSize == 4); | 2707 STATIC_ASSERT(kPointerSize == 4); |
2708 __ mov(ip, Operand(DescriptorArray::kDescriptorSize)); | 2708 __ mov(ip, Operand(DescriptorArray::kDescriptorSize)); |
2709 __ mul(r3, r3, ip); | 2709 __ mul(r3, r3, ip); |
2710 // Calculate location of the first key name. | 2710 // Calculate location of the first key name. |
2711 __ add(r4, r4, Operand(DescriptorArray::kFirstOffset - kHeapObjectTag)); | 2711 __ add(r4, r4, Operand(DescriptorArray::kFirstOffset - kHeapObjectTag)); |
2712 // Calculate the end of the descriptor array. | 2712 // Calculate the end of the descriptor array. |
2713 __ mov(r2, r4); | 2713 __ mov(r2, r4); |
2714 __ add(r2, r2, Operand(r3, LSL, kPointerSizeLog2 - kSmiTagSize)); | 2714 __ add(r2, r2, Operand(r3, LSL, kPointerSizeLog2 - kSmiTagSize)); |
2715 | 2715 |
2716 // Loop through all the keys in the descriptor array. If one of these is the | 2716 // Loop through all the keys in the descriptor array. If one of these is the |
2717 // symbol valueOf the result is false. | 2717 // string "valueOf" the result is false. |
2718 // The use of ip to store the valueOf symbol asumes that it is not otherwise | 2718 // The use of ip to store the valueOf string assumes that it is not otherwise |
2719 // used in the loop below. | 2719 // used in the loop below. |
2720 __ mov(ip, Operand(FACTORY->value_of_symbol())); | 2720 __ mov(ip, Operand(FACTORY->value_of_string())); |
2721 __ jmp(&entry); | 2721 __ jmp(&entry); |
2722 __ bind(&loop); | 2722 __ bind(&loop); |
2723 __ ldr(r3, MemOperand(r4, 0)); | 2723 __ ldr(r3, MemOperand(r4, 0)); |
2724 __ cmp(r3, ip); | 2724 __ cmp(r3, ip); |
2725 __ b(eq, if_false); | 2725 __ b(eq, if_false); |
2726 __ add(r4, r4, Operand(DescriptorArray::kDescriptorSize * kPointerSize)); | 2726 __ add(r4, r4, Operand(DescriptorArray::kDescriptorSize * kPointerSize)); |
2727 __ bind(&entry); | 2727 __ bind(&entry); |
2728 __ cmp(r4, Operand(r2)); | 2728 __ cmp(r4, Operand(r2)); |
2729 __ b(ne, &loop); | 2729 __ b(ne, &loop); |
2730 | 2730 |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2945 __ b(ne, &non_function_constructor); | 2945 __ b(ne, &non_function_constructor); |
2946 | 2946 |
2947 // r0 now contains the constructor function. Grab the | 2947 // r0 now contains the constructor function. Grab the |
2948 // instance class name from there. | 2948 // instance class name from there. |
2949 __ ldr(r0, FieldMemOperand(r0, JSFunction::kSharedFunctionInfoOffset)); | 2949 __ ldr(r0, FieldMemOperand(r0, JSFunction::kSharedFunctionInfoOffset)); |
2950 __ ldr(r0, FieldMemOperand(r0, SharedFunctionInfo::kInstanceClassNameOffset)); | 2950 __ ldr(r0, FieldMemOperand(r0, SharedFunctionInfo::kInstanceClassNameOffset)); |
2951 __ b(&done); | 2951 __ b(&done); |
2952 | 2952 |
2953 // Functions have class 'Function'. | 2953 // Functions have class 'Function'. |
2954 __ bind(&function); | 2954 __ bind(&function); |
2955 __ LoadRoot(r0, Heap::kfunction_class_symbolRootIndex); | 2955 __ LoadRoot(r0, Heap::kfunction_class_stringRootIndex); |
2956 __ jmp(&done); | 2956 __ jmp(&done); |
2957 | 2957 |
2958 // Objects with a non-function constructor have class 'Object'. | 2958 // Objects with a non-function constructor have class 'Object'. |
2959 __ bind(&non_function_constructor); | 2959 __ bind(&non_function_constructor); |
2960 __ LoadRoot(r0, Heap::kObject_symbolRootIndex); | 2960 __ LoadRoot(r0, Heap::kObject_stringRootIndex); |
2961 __ jmp(&done); | 2961 __ jmp(&done); |
2962 | 2962 |
2963 // Non-JS objects have class null. | 2963 // Non-JS objects have class null. |
2964 __ bind(&null); | 2964 __ bind(&null); |
2965 __ LoadRoot(r0, Heap::kNullValueRootIndex); | 2965 __ LoadRoot(r0, Heap::kNullValueRootIndex); |
2966 | 2966 |
2967 // All done. | 2967 // All done. |
2968 __ bind(&done); | 2968 __ bind(&done); |
2969 | 2969 |
2970 context()->Plug(r0); | 2970 context()->Plug(r0); |
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3315 &need_conversion, | 3315 &need_conversion, |
3316 &need_conversion, | 3316 &need_conversion, |
3317 &index_out_of_range, | 3317 &index_out_of_range, |
3318 STRING_INDEX_IS_NUMBER); | 3318 STRING_INDEX_IS_NUMBER); |
3319 generator.GenerateFast(masm_); | 3319 generator.GenerateFast(masm_); |
3320 __ jmp(&done); | 3320 __ jmp(&done); |
3321 | 3321 |
3322 __ bind(&index_out_of_range); | 3322 __ bind(&index_out_of_range); |
3323 // When the index is out of range, the spec requires us to return | 3323 // When the index is out of range, the spec requires us to return |
3324 // the empty string. | 3324 // the empty string. |
3325 __ LoadRoot(result, Heap::kEmptyStringRootIndex); | 3325 __ LoadRoot(result, Heap::kempty_stringRootIndex); |
3326 __ jmp(&done); | 3326 __ jmp(&done); |
3327 | 3327 |
3328 __ bind(&need_conversion); | 3328 __ bind(&need_conversion); |
3329 // Move smi zero into the result register, which will trigger | 3329 // Move smi zero into the result register, which will trigger |
3330 // conversion. | 3330 // conversion. |
3331 __ mov(result, Operand(Smi::FromInt(0))); | 3331 __ mov(result, Operand(Smi::FromInt(0))); |
3332 __ jmp(&done); | 3332 __ jmp(&done); |
3333 | 3333 |
3334 NopRuntimeCallHelper call_helper; | 3334 NopRuntimeCallHelper call_helper; |
3335 generator.GenerateSlow(masm_, call_helper); | 3335 generator.GenerateSlow(masm_, call_helper); |
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3624 __ CompareObjectType(array, scratch1, scratch2, JS_ARRAY_TYPE); | 3624 __ CompareObjectType(array, scratch1, scratch2, JS_ARRAY_TYPE); |
3625 __ b(ne, &bailout); | 3625 __ b(ne, &bailout); |
3626 | 3626 |
3627 // Check that the array has fast elements. | 3627 // Check that the array has fast elements. |
3628 __ CheckFastElements(scratch1, scratch2, &bailout); | 3628 __ CheckFastElements(scratch1, scratch2, &bailout); |
3629 | 3629 |
3630 // If the array has length zero, return the empty string. | 3630 // If the array has length zero, return the empty string. |
3631 __ ldr(array_length, FieldMemOperand(array, JSArray::kLengthOffset)); | 3631 __ ldr(array_length, FieldMemOperand(array, JSArray::kLengthOffset)); |
3632 __ SmiUntag(array_length, SetCC); | 3632 __ SmiUntag(array_length, SetCC); |
3633 __ b(ne, &non_trivial_array); | 3633 __ b(ne, &non_trivial_array); |
3634 __ LoadRoot(r0, Heap::kEmptyStringRootIndex); | 3634 __ LoadRoot(r0, Heap::kempty_stringRootIndex); |
3635 __ b(&done); | 3635 __ b(&done); |
3636 | 3636 |
3637 __ bind(&non_trivial_array); | 3637 __ bind(&non_trivial_array); |
3638 | 3638 |
3639 // Get the FixedArray containing array's elements. | 3639 // Get the FixedArray containing array's elements. |
3640 elements = array; | 3640 elements = array; |
3641 __ ldr(elements, FieldMemOperand(array, JSArray::kElementsOffset)); | 3641 __ ldr(elements, FieldMemOperand(array, JSArray::kElementsOffset)); |
3642 array = no_reg; // End of array's live range. | 3642 array = no_reg; // End of array's live range. |
3643 | 3643 |
3644 // Check that all array elements are sequential ASCII strings, and | 3644 // Check that all array elements are sequential ASCII strings, and |
(...skipping 590 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4235 Label* if_false = NULL; | 4235 Label* if_false = NULL; |
4236 Label* fall_through = NULL; | 4236 Label* fall_through = NULL; |
4237 context()->PrepareTest(&materialize_true, &materialize_false, | 4237 context()->PrepareTest(&materialize_true, &materialize_false, |
4238 &if_true, &if_false, &fall_through); | 4238 &if_true, &if_false, &fall_through); |
4239 | 4239 |
4240 { AccumulatorValueContext context(this); | 4240 { AccumulatorValueContext context(this); |
4241 VisitForTypeofValue(sub_expr); | 4241 VisitForTypeofValue(sub_expr); |
4242 } | 4242 } |
4243 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); | 4243 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
4244 | 4244 |
4245 if (check->Equals(isolate()->heap()->number_symbol())) { | 4245 if (check->Equals(isolate()->heap()->number_string())) { |
4246 __ JumpIfSmi(r0, if_true); | 4246 __ JumpIfSmi(r0, if_true); |
4247 __ ldr(r0, FieldMemOperand(r0, HeapObject::kMapOffset)); | 4247 __ ldr(r0, FieldMemOperand(r0, HeapObject::kMapOffset)); |
4248 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); | 4248 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); |
4249 __ cmp(r0, ip); | 4249 __ cmp(r0, ip); |
4250 Split(eq, if_true, if_false, fall_through); | 4250 Split(eq, if_true, if_false, fall_through); |
4251 } else if (check->Equals(isolate()->heap()->string_symbol())) { | 4251 } else if (check->Equals(isolate()->heap()->string_string())) { |
4252 __ JumpIfSmi(r0, if_false); | 4252 __ JumpIfSmi(r0, if_false); |
4253 // Check for undetectable objects => false. | 4253 // Check for undetectable objects => false. |
4254 __ CompareObjectType(r0, r0, r1, FIRST_NONSTRING_TYPE); | 4254 __ CompareObjectType(r0, r0, r1, FIRST_NONSTRING_TYPE); |
4255 __ b(ge, if_false); | 4255 __ b(ge, if_false); |
4256 __ ldrb(r1, FieldMemOperand(r0, Map::kBitFieldOffset)); | 4256 __ ldrb(r1, FieldMemOperand(r0, Map::kBitFieldOffset)); |
4257 __ tst(r1, Operand(1 << Map::kIsUndetectable)); | 4257 __ tst(r1, Operand(1 << Map::kIsUndetectable)); |
4258 Split(eq, if_true, if_false, fall_through); | 4258 Split(eq, if_true, if_false, fall_through); |
4259 } else if (check->Equals(isolate()->heap()->boolean_symbol())) { | 4259 } else if (check->Equals(isolate()->heap()->boolean_string())) { |
4260 __ CompareRoot(r0, Heap::kTrueValueRootIndex); | 4260 __ CompareRoot(r0, Heap::kTrueValueRootIndex); |
4261 __ b(eq, if_true); | 4261 __ b(eq, if_true); |
4262 __ CompareRoot(r0, Heap::kFalseValueRootIndex); | 4262 __ CompareRoot(r0, Heap::kFalseValueRootIndex); |
4263 Split(eq, if_true, if_false, fall_through); | 4263 Split(eq, if_true, if_false, fall_through); |
4264 } else if (FLAG_harmony_typeof && | 4264 } else if (FLAG_harmony_typeof && |
4265 check->Equals(isolate()->heap()->null_symbol())) { | 4265 check->Equals(isolate()->heap()->null_string())) { |
4266 __ CompareRoot(r0, Heap::kNullValueRootIndex); | 4266 __ CompareRoot(r0, Heap::kNullValueRootIndex); |
4267 Split(eq, if_true, if_false, fall_through); | 4267 Split(eq, if_true, if_false, fall_through); |
4268 } else if (check->Equals(isolate()->heap()->undefined_symbol())) { | 4268 } else if (check->Equals(isolate()->heap()->undefined_string())) { |
4269 __ CompareRoot(r0, Heap::kUndefinedValueRootIndex); | 4269 __ CompareRoot(r0, Heap::kUndefinedValueRootIndex); |
4270 __ b(eq, if_true); | 4270 __ b(eq, if_true); |
4271 __ JumpIfSmi(r0, if_false); | 4271 __ JumpIfSmi(r0, if_false); |
4272 // Check for undetectable objects => true. | 4272 // Check for undetectable objects => true. |
4273 __ ldr(r0, FieldMemOperand(r0, HeapObject::kMapOffset)); | 4273 __ ldr(r0, FieldMemOperand(r0, HeapObject::kMapOffset)); |
4274 __ ldrb(r1, FieldMemOperand(r0, Map::kBitFieldOffset)); | 4274 __ ldrb(r1, FieldMemOperand(r0, Map::kBitFieldOffset)); |
4275 __ tst(r1, Operand(1 << Map::kIsUndetectable)); | 4275 __ tst(r1, Operand(1 << Map::kIsUndetectable)); |
4276 Split(ne, if_true, if_false, fall_through); | 4276 Split(ne, if_true, if_false, fall_through); |
4277 | 4277 |
4278 } else if (check->Equals(isolate()->heap()->function_symbol())) { | 4278 } else if (check->Equals(isolate()->heap()->function_string())) { |
4279 __ JumpIfSmi(r0, if_false); | 4279 __ JumpIfSmi(r0, if_false); |
4280 STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2); | 4280 STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2); |
4281 __ CompareObjectType(r0, r0, r1, JS_FUNCTION_TYPE); | 4281 __ CompareObjectType(r0, r0, r1, JS_FUNCTION_TYPE); |
4282 __ b(eq, if_true); | 4282 __ b(eq, if_true); |
4283 __ cmp(r1, Operand(JS_FUNCTION_PROXY_TYPE)); | 4283 __ cmp(r1, Operand(JS_FUNCTION_PROXY_TYPE)); |
4284 Split(eq, if_true, if_false, fall_through); | 4284 Split(eq, if_true, if_false, fall_through); |
4285 } else if (check->Equals(isolate()->heap()->object_symbol())) { | 4285 } else if (check->Equals(isolate()->heap()->object_string())) { |
4286 __ JumpIfSmi(r0, if_false); | 4286 __ JumpIfSmi(r0, if_false); |
4287 if (!FLAG_harmony_typeof) { | 4287 if (!FLAG_harmony_typeof) { |
4288 __ CompareRoot(r0, Heap::kNullValueRootIndex); | 4288 __ CompareRoot(r0, Heap::kNullValueRootIndex); |
4289 __ b(eq, if_true); | 4289 __ b(eq, if_true); |
4290 } | 4290 } |
4291 // Check for JS objects => true. | 4291 // Check for JS objects => true. |
4292 __ CompareObjectType(r0, r0, r1, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE); | 4292 __ CompareObjectType(r0, r0, r1, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE); |
4293 __ b(lt, if_false); | 4293 __ b(lt, if_false); |
4294 __ CompareInstanceType(r0, r1, LAST_NONCALLABLE_SPEC_OBJECT_TYPE); | 4294 __ CompareInstanceType(r0, r1, LAST_NONCALLABLE_SPEC_OBJECT_TYPE); |
4295 __ b(gt, if_false); | 4295 __ b(gt, if_false); |
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4562 *context_length = 0; | 4562 *context_length = 0; |
4563 return previous_; | 4563 return previous_; |
4564 } | 4564 } |
4565 | 4565 |
4566 | 4566 |
4567 #undef __ | 4567 #undef __ |
4568 | 4568 |
4569 } } // namespace v8::internal | 4569 } } // namespace v8::internal |
4570 | 4570 |
4571 #endif // V8_TARGET_ARCH_ARM | 4571 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |