OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #if V8_TARGET_ARCH_ARM64 | 5 #if V8_TARGET_ARCH_ARM64 |
6 | 6 |
7 #include "src/code-factory.h" | 7 #include "src/code-factory.h" |
8 #include "src/code-stubs.h" | 8 #include "src/code-stubs.h" |
9 #include "src/codegen.h" | 9 #include "src/codegen.h" |
10 #include "src/compiler.h" | 10 #include "src/compiler.h" |
(...skipping 3013 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3024 | 3024 |
3025 __ JumpIfSmi(x0, if_false); | 3025 __ JumpIfSmi(x0, if_false); |
3026 __ CompareObjectType(x0, x10, x11, SIMD128_VALUE_TYPE); | 3026 __ CompareObjectType(x0, x10, x11, SIMD128_VALUE_TYPE); |
3027 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); | 3027 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
3028 Split(eq, if_true, if_false, fall_through); | 3028 Split(eq, if_true, if_false, fall_through); |
3029 | 3029 |
3030 context()->Plug(if_true, if_false); | 3030 context()->Plug(if_true, if_false); |
3031 } | 3031 } |
3032 | 3032 |
3033 | 3033 |
3034 void FullCodeGenerator::EmitIsStringWrapperSafeForDefaultValueOf( | |
3035 CallRuntime* expr) { | |
3036 ZoneList<Expression*>* args = expr->arguments(); | |
3037 DCHECK(args->length() == 1); | |
3038 VisitForAccumulatorValue(args->at(0)); | |
3039 | |
3040 Label materialize_true, materialize_false, skip_lookup; | |
3041 Label* if_true = NULL; | |
3042 Label* if_false = NULL; | |
3043 Label* fall_through = NULL; | |
3044 context()->PrepareTest(&materialize_true, &materialize_false, | |
3045 &if_true, &if_false, &fall_through); | |
3046 | |
3047 Register object = x0; | |
3048 __ AssertNotSmi(object); | |
3049 | |
3050 Register map = x10; | |
3051 Register bitfield2 = x11; | |
3052 __ Ldr(map, FieldMemOperand(object, HeapObject::kMapOffset)); | |
3053 __ Ldrb(bitfield2, FieldMemOperand(map, Map::kBitField2Offset)); | |
3054 __ Tbnz(bitfield2, Map::kStringWrapperSafeForDefaultValueOf, &skip_lookup); | |
3055 | |
3056 // Check for fast case object. Generate false result for slow case object. | |
3057 Register props = x12; | |
3058 Register props_map = x12; | |
3059 Register hash_table_map = x13; | |
3060 __ Ldr(props, FieldMemOperand(object, JSObject::kPropertiesOffset)); | |
3061 __ Ldr(props_map, FieldMemOperand(props, HeapObject::kMapOffset)); | |
3062 __ LoadRoot(hash_table_map, Heap::kHashTableMapRootIndex); | |
3063 __ Cmp(props_map, hash_table_map); | |
3064 __ B(eq, if_false); | |
3065 | |
3066 // Look for valueOf name in the descriptor array, and indicate false if found. | |
3067 // Since we omit an enumeration index check, if it is added via a transition | |
3068 // that shares its descriptor array, this is a false positive. | |
3069 Label loop, done; | |
3070 | |
3071 // Skip loop if no descriptors are valid. | |
3072 Register descriptors = x12; | |
3073 Register descriptors_length = x13; | |
3074 __ NumberOfOwnDescriptors(descriptors_length, map); | |
3075 __ Cbz(descriptors_length, &done); | |
3076 | |
3077 __ LoadInstanceDescriptors(map, descriptors); | |
3078 | |
3079 // Calculate the end of the descriptor array. | |
3080 Register descriptors_end = x14; | |
3081 __ Mov(x15, DescriptorArray::kDescriptorSize); | |
3082 __ Mul(descriptors_length, descriptors_length, x15); | |
3083 // Calculate location of the first key name. | |
3084 __ Add(descriptors, descriptors, | |
3085 DescriptorArray::kFirstOffset - kHeapObjectTag); | |
3086 // Calculate the end of the descriptor array. | |
3087 __ Add(descriptors_end, descriptors, | |
3088 Operand(descriptors_length, LSL, kPointerSizeLog2)); | |
3089 | |
3090 // Loop through all the keys in the descriptor array. If one of these is the | |
3091 // string "valueOf" the result is false. | |
3092 Register valueof_string = x1; | |
3093 int descriptor_size = DescriptorArray::kDescriptorSize * kPointerSize; | |
3094 __ LoadRoot(valueof_string, Heap::kvalueOf_stringRootIndex); | |
3095 __ Bind(&loop); | |
3096 __ Ldr(x15, MemOperand(descriptors, descriptor_size, PostIndex)); | |
3097 __ Cmp(x15, valueof_string); | |
3098 __ B(eq, if_false); | |
3099 __ Cmp(descriptors, descriptors_end); | |
3100 __ B(ne, &loop); | |
3101 | |
3102 __ Bind(&done); | |
3103 | |
3104 // Set the bit in the map to indicate that there is no local valueOf field. | |
3105 __ Ldrb(x2, FieldMemOperand(map, Map::kBitField2Offset)); | |
3106 __ Orr(x2, x2, 1 << Map::kStringWrapperSafeForDefaultValueOf); | |
3107 __ Strb(x2, FieldMemOperand(map, Map::kBitField2Offset)); | |
3108 | |
3109 __ Bind(&skip_lookup); | |
3110 | |
3111 // If a valueOf property is not found on the object check that its prototype | |
3112 // is the unmodified String prototype. If not result is false. | |
3113 Register prototype = x1; | |
3114 Register global_idx = x2; | |
3115 Register native_context = x2; | |
3116 Register string_proto = x3; | |
3117 Register proto_map = x4; | |
3118 __ Ldr(prototype, FieldMemOperand(map, Map::kPrototypeOffset)); | |
3119 __ JumpIfSmi(prototype, if_false); | |
3120 __ Ldr(proto_map, FieldMemOperand(prototype, HeapObject::kMapOffset)); | |
3121 __ Ldr(global_idx, GlobalObjectMemOperand()); | |
3122 __ Ldr(native_context, | |
3123 FieldMemOperand(global_idx, GlobalObject::kNativeContextOffset)); | |
3124 __ Ldr(string_proto, | |
3125 ContextMemOperand(native_context, | |
3126 Context::STRING_FUNCTION_PROTOTYPE_MAP_INDEX)); | |
3127 __ Cmp(proto_map, string_proto); | |
3128 | |
3129 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); | |
3130 Split(eq, if_true, if_false, fall_through); | |
3131 | |
3132 context()->Plug(if_true, if_false); | |
3133 } | |
3134 | |
3135 | |
3136 void FullCodeGenerator::EmitIsFunction(CallRuntime* expr) { | 3034 void FullCodeGenerator::EmitIsFunction(CallRuntime* expr) { |
3137 ZoneList<Expression*>* args = expr->arguments(); | 3035 ZoneList<Expression*>* args = expr->arguments(); |
3138 DCHECK(args->length() == 1); | 3036 DCHECK(args->length() == 1); |
3139 | 3037 |
3140 VisitForAccumulatorValue(args->at(0)); | 3038 VisitForAccumulatorValue(args->at(0)); |
3141 | 3039 |
3142 Label materialize_true, materialize_false; | 3040 Label materialize_true, materialize_false; |
3143 Label* if_true = NULL; | 3041 Label* if_true = NULL; |
3144 Label* if_false = NULL; | 3042 Label* if_false = NULL; |
3145 Label* fall_through = NULL; | 3043 Label* fall_through = NULL; |
(...skipping 2220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5366 } | 5264 } |
5367 | 5265 |
5368 return INTERRUPT; | 5266 return INTERRUPT; |
5369 } | 5267 } |
5370 | 5268 |
5371 | 5269 |
5372 } // namespace internal | 5270 } // namespace internal |
5373 } // namespace v8 | 5271 } // namespace v8 |
5374 | 5272 |
5375 #endif // V8_TARGET_ARCH_ARM64 | 5273 #endif // V8_TARGET_ARCH_ARM64 |
OLD | NEW |