| 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/ast/scopes.h" |     7 #include "src/ast/scopes.h" | 
|     8 #include "src/code-factory.h" |     8 #include "src/code-factory.h" | 
|     9 #include "src/code-stubs.h" |     9 #include "src/code-stubs.h" | 
|    10 #include "src/codegen.h" |    10 #include "src/codegen.h" | 
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   112   if (strlen(FLAG_stop_at) > 0 && |   112   if (strlen(FLAG_stop_at) > 0 && | 
|   113       info->literal()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) { |   113       info->literal()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) { | 
|   114     __ Debug("stop-at", __LINE__, BREAK); |   114     __ Debug("stop-at", __LINE__, BREAK); | 
|   115   } |   115   } | 
|   116 #endif |   116 #endif | 
|   117  |   117  | 
|   118   if (FLAG_debug_code && info->ExpectsJSReceiverAsReceiver()) { |   118   if (FLAG_debug_code && info->ExpectsJSReceiverAsReceiver()) { | 
|   119     int receiver_offset = info->scope()->num_parameters() * kXRegSize; |   119     int receiver_offset = info->scope()->num_parameters() * kXRegSize; | 
|   120     __ Peek(x10, receiver_offset); |   120     __ Peek(x10, receiver_offset); | 
|   121     __ AssertNotSmi(x10); |   121     __ AssertNotSmi(x10); | 
|   122     __ CompareObjectType(x10, x10, x11, FIRST_SPEC_OBJECT_TYPE); |   122     __ CompareObjectType(x10, x10, x11, FIRST_JS_RECEIVER_TYPE); | 
|   123     __ Assert(ge, kSloppyFunctionExpectsJSReceiverReceiver); |   123     __ Assert(ge, kSloppyFunctionExpectsJSReceiverReceiver); | 
|   124   } |   124   } | 
|   125  |   125  | 
|   126   // Open a frame scope to indicate that there is a frame on the stack. |   126   // Open a frame scope to indicate that there is a frame on the stack. | 
|   127   // The MANUAL indicates that the scope shouldn't actually generate code |   127   // The MANUAL indicates that the scope shouldn't actually generate code | 
|   128   // to set up the frame because we do it manually below. |   128   // to set up the frame because we do it manually below. | 
|   129   FrameScope frame_scope(masm_, StackFrame::MANUAL); |   129   FrameScope frame_scope(masm_, StackFrame::MANUAL); | 
|   130  |   130  | 
|   131   // This call emits the following sequence in a way that can be patched for |   131   // This call emits the following sequence in a way that can be patched for | 
|   132   // code ageing support: |   132   // code ageing support: | 
| (...skipping 907 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1040   Register null_value = x15; |  1040   Register null_value = x15; | 
|  1041   __ LoadRoot(null_value, Heap::kNullValueRootIndex); |  1041   __ LoadRoot(null_value, Heap::kNullValueRootIndex); | 
|  1042   __ Cmp(x0, null_value); |  1042   __ Cmp(x0, null_value); | 
|  1043   __ B(eq, &exit); |  1043   __ B(eq, &exit); | 
|  1044  |  1044  | 
|  1045   PrepareForBailoutForId(stmt->PrepareId(), TOS_REG); |  1045   PrepareForBailoutForId(stmt->PrepareId(), TOS_REG); | 
|  1046  |  1046  | 
|  1047   // Convert the object to a JS object. |  1047   // Convert the object to a JS object. | 
|  1048   Label convert, done_convert; |  1048   Label convert, done_convert; | 
|  1049   __ JumpIfSmi(x0, &convert); |  1049   __ JumpIfSmi(x0, &convert); | 
|  1050   __ JumpIfObjectType(x0, x10, x11, FIRST_SPEC_OBJECT_TYPE, &done_convert, ge); |  1050   __ JumpIfObjectType(x0, x10, x11, FIRST_JS_RECEIVER_TYPE, &done_convert, ge); | 
|  1051   __ Bind(&convert); |  1051   __ Bind(&convert); | 
|  1052   ToObjectStub stub(isolate()); |  1052   ToObjectStub stub(isolate()); | 
|  1053   __ CallStub(&stub); |  1053   __ CallStub(&stub); | 
|  1054   __ Bind(&done_convert); |  1054   __ Bind(&done_convert); | 
|  1055   PrepareForBailoutForId(stmt->ToObjectId(), TOS_REG); |  1055   PrepareForBailoutForId(stmt->ToObjectId(), TOS_REG); | 
|  1056   __ Push(x0); |  1056   __ Push(x0); | 
|  1057  |  1057  | 
|  1058   // Check for proxies. |  1058   // Check for proxies. | 
|  1059   Label call_runtime; |  1059   Label call_runtime; | 
|  1060   STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE); |  1060   STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_JS_RECEIVER_TYPE); | 
|  1061   __ JumpIfObjectType(x0, x10, x11, LAST_JS_PROXY_TYPE, &call_runtime, le); |  1061   __ JumpIfObjectType(x0, x10, x11, LAST_JS_PROXY_TYPE, &call_runtime, le); | 
|  1062  |  1062  | 
|  1063   // Check cache validity in generated code. This is a fast case for |  1063   // Check cache validity in generated code. This is a fast case for | 
|  1064   // the JSObject::IsSimpleEnum cache validity checks. If we cannot |  1064   // the JSObject::IsSimpleEnum cache validity checks. If we cannot | 
|  1065   // guarantee cache validity, call the runtime system to check cache |  1065   // guarantee cache validity, call the runtime system to check cache | 
|  1066   // validity or get the property names in a fixed array. |  1066   // validity or get the property names in a fixed array. | 
|  1067   __ CheckEnumCache(x0, null_value, x10, x11, x12, x13, &call_runtime); |  1067   __ CheckEnumCache(x0, null_value, x10, x11, x12, x13, &call_runtime); | 
|  1068  |  1068  | 
|  1069   // The enum cache is valid.  Load the map of the object being |  1069   // The enum cache is valid.  Load the map of the object being | 
|  1070   // iterated over and use the cache for the iteration. |  1070   // iterated over and use the cache for the iteration. | 
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1109   // We got a fixed array in register x0. Iterate through that. |  1109   // We got a fixed array in register x0. Iterate through that. | 
|  1110   __ Bind(&fixed_array); |  1110   __ Bind(&fixed_array); | 
|  1111  |  1111  | 
|  1112   __ EmitLoadTypeFeedbackVector(x1); |  1112   __ EmitLoadTypeFeedbackVector(x1); | 
|  1113   __ Mov(x10, Operand(TypeFeedbackVector::MegamorphicSentinel(isolate()))); |  1113   __ Mov(x10, Operand(TypeFeedbackVector::MegamorphicSentinel(isolate()))); | 
|  1114   int vector_index = SmiFromSlot(slot)->value(); |  1114   int vector_index = SmiFromSlot(slot)->value(); | 
|  1115   __ Str(x10, FieldMemOperand(x1, FixedArray::OffsetOfElementAt(vector_index))); |  1115   __ Str(x10, FieldMemOperand(x1, FixedArray::OffsetOfElementAt(vector_index))); | 
|  1116  |  1116  | 
|  1117   __ Mov(x1, Smi::FromInt(1));  // Smi indicates slow check. |  1117   __ Mov(x1, Smi::FromInt(1));  // Smi indicates slow check. | 
|  1118   __ Peek(x10, 0);  // Get enumerated object. |  1118   __ Peek(x10, 0);  // Get enumerated object. | 
|  1119   STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE); |  1119   STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_JS_RECEIVER_TYPE); | 
|  1120   // TODO(all): similar check was done already. Can we avoid it here? |  1120   // TODO(all): similar check was done already. Can we avoid it here? | 
|  1121   __ CompareObjectType(x10, x11, x12, LAST_JS_PROXY_TYPE); |  1121   __ CompareObjectType(x10, x11, x12, LAST_JS_PROXY_TYPE); | 
|  1122   DCHECK(Smi::FromInt(0) == 0); |  1122   DCHECK(Smi::FromInt(0) == 0); | 
|  1123   __ CzeroX(x1, le);  // Zero indicates proxy. |  1123   __ CzeroX(x1, le);  // Zero indicates proxy. | 
|  1124   __ Ldr(x2, FieldMemOperand(x0, FixedArray::kLengthOffset)); |  1124   __ Ldr(x2, FieldMemOperand(x0, FixedArray::kLengthOffset)); | 
|  1125   // Smi and array, fixed array length (as smi) and initial index. |  1125   // Smi and array, fixed array length (as smi) and initial index. | 
|  1126   __ Push(x1, x0, x2, xzr); |  1126   __ Push(x1, x0, x2, xzr); | 
|  1127  |  1127  | 
|  1128   // Generate code for doing the condition check. |  1128   // Generate code for doing the condition check. | 
|  1129   __ Bind(&loop); |  1129   __ Bind(&loop); | 
| (...skipping 1680 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  2810   VisitForAccumulatorValue(args->at(0)); |  2810   VisitForAccumulatorValue(args->at(0)); | 
|  2811  |  2811  | 
|  2812   Label materialize_true, materialize_false; |  2812   Label materialize_true, materialize_false; | 
|  2813   Label* if_true = NULL; |  2813   Label* if_true = NULL; | 
|  2814   Label* if_false = NULL; |  2814   Label* if_false = NULL; | 
|  2815   Label* fall_through = NULL; |  2815   Label* fall_through = NULL; | 
|  2816   context()->PrepareTest(&materialize_true, &materialize_false, |  2816   context()->PrepareTest(&materialize_true, &materialize_false, | 
|  2817                          &if_true, &if_false, &fall_through); |  2817                          &if_true, &if_false, &fall_through); | 
|  2818  |  2818  | 
|  2819   __ JumpIfSmi(x0, if_false); |  2819   __ JumpIfSmi(x0, if_false); | 
|  2820   __ CompareObjectType(x0, x10, x11, FIRST_SPEC_OBJECT_TYPE); |  2820   __ CompareObjectType(x0, x10, x11, FIRST_JS_RECEIVER_TYPE); | 
|  2821   PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |  2821   PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); | 
|  2822   Split(ge, if_true, if_false, fall_through); |  2822   Split(ge, if_true, if_false, fall_through); | 
|  2823  |  2823  | 
|  2824   context()->Plug(if_true, if_false); |  2824   context()->Plug(if_true, if_false); | 
|  2825 } |  2825 } | 
|  2826  |  2826  | 
|  2827  |  2827  | 
|  2828 void FullCodeGenerator::EmitIsSimdValue(CallRuntime* expr) { |  2828 void FullCodeGenerator::EmitIsSimdValue(CallRuntime* expr) { | 
|  2829   ZoneList<Expression*>* args = expr->arguments(); |  2829   ZoneList<Expression*>* args = expr->arguments(); | 
|  2830   DCHECK(args->length() == 1); |  2830   DCHECK(args->length() == 1); | 
| (...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  3088   VisitForAccumulatorValue(args->at(0)); |  3088   VisitForAccumulatorValue(args->at(0)); | 
|  3089  |  3089  | 
|  3090   // If the object is a smi, we return null. |  3090   // If the object is a smi, we return null. | 
|  3091   __ JumpIfSmi(x0, &null); |  3091   __ JumpIfSmi(x0, &null); | 
|  3092  |  3092  | 
|  3093   // Check that the object is a JS object but take special care of JS |  3093   // Check that the object is a JS object but take special care of JS | 
|  3094   // functions to make sure they have 'Function' as their class. |  3094   // functions to make sure they have 'Function' as their class. | 
|  3095   // Assume that there are only two callable types, and one of them is at |  3095   // Assume that there are only two callable types, and one of them is at | 
|  3096   // either end of the type range for JS object types. Saves extra comparisons. |  3096   // either end of the type range for JS object types. Saves extra comparisons. | 
|  3097   STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2); |  3097   STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2); | 
|  3098   __ CompareObjectType(x0, x10, x11, FIRST_SPEC_OBJECT_TYPE); |  3098   __ CompareObjectType(x0, x10, x11, FIRST_JS_RECEIVER_TYPE); | 
|  3099   // x10: object's map. |  3099   // x10: object's map. | 
|  3100   // x11: object's type. |  3100   // x11: object's type. | 
|  3101   __ B(lt, &null); |  3101   __ B(lt, &null); | 
|  3102   STATIC_ASSERT(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE == |  3102   STATIC_ASSERT(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE == | 
|  3103                 FIRST_SPEC_OBJECT_TYPE + 1); |  3103                 FIRST_JS_RECEIVER_TYPE + 1); | 
|  3104   __ B(eq, &function); |  3104   __ B(eq, &function); | 
|  3105  |  3105  | 
|  3106   __ Cmp(x11, LAST_SPEC_OBJECT_TYPE); |  3106   __ Cmp(x11, LAST_JS_RECEIVER_TYPE); | 
|  3107   STATIC_ASSERT(LAST_NONCALLABLE_SPEC_OBJECT_TYPE == |  3107   STATIC_ASSERT(LAST_NONCALLABLE_SPEC_OBJECT_TYPE == | 
|  3108                 LAST_SPEC_OBJECT_TYPE - 1); |  3108                 LAST_JS_RECEIVER_TYPE - 1); | 
|  3109   __ B(eq, &function); |  3109   __ B(eq, &function); | 
|  3110   // Assume that there is no larger type. |  3110   // Assume that there is no larger type. | 
|  3111   STATIC_ASSERT(LAST_NONCALLABLE_SPEC_OBJECT_TYPE == LAST_TYPE - 1); |  3111   STATIC_ASSERT(LAST_NONCALLABLE_SPEC_OBJECT_TYPE == LAST_TYPE - 1); | 
|  3112  |  3112  | 
|  3113   // Check if the constructor in the map is a JS function. |  3113   // Check if the constructor in the map is a JS function. | 
|  3114   Register instance_type = x14; |  3114   Register instance_type = x14; | 
|  3115   __ GetMapConstructor(x12, x10, x13, instance_type); |  3115   __ GetMapConstructor(x12, x10, x13, instance_type); | 
|  3116   __ Cmp(instance_type, JS_FUNCTION_TYPE); |  3116   __ Cmp(instance_type, JS_FUNCTION_TYPE); | 
|  3117   __ B(ne, &non_function_constructor); |  3117   __ B(ne, &non_function_constructor); | 
|  3118  |  3118  | 
| (...skipping 1215 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  4334     __ JumpIfSmi(x0, if_false); |  4334     __ JumpIfSmi(x0, if_false); | 
|  4335     __ Ldr(x0, FieldMemOperand(x0, HeapObject::kMapOffset)); |  4335     __ Ldr(x0, FieldMemOperand(x0, HeapObject::kMapOffset)); | 
|  4336     __ Ldrb(x1, FieldMemOperand(x0, Map::kBitFieldOffset)); |  4336     __ Ldrb(x1, FieldMemOperand(x0, Map::kBitFieldOffset)); | 
|  4337     __ And(x1, x1, (1 << Map::kIsCallable) | (1 << Map::kIsUndetectable)); |  4337     __ And(x1, x1, (1 << Map::kIsCallable) | (1 << Map::kIsUndetectable)); | 
|  4338     __ CompareAndSplit(x1, Operand(1 << Map::kIsCallable), eq, if_true, |  4338     __ CompareAndSplit(x1, Operand(1 << Map::kIsCallable), eq, if_true, | 
|  4339                        if_false, fall_through); |  4339                        if_false, fall_through); | 
|  4340   } else if (String::Equals(check, factory->object_string())) { |  4340   } else if (String::Equals(check, factory->object_string())) { | 
|  4341     ASM_LOCATION("FullCodeGenerator::EmitLiteralCompareTypeof object_string"); |  4341     ASM_LOCATION("FullCodeGenerator::EmitLiteralCompareTypeof object_string"); | 
|  4342     __ JumpIfSmi(x0, if_false); |  4342     __ JumpIfSmi(x0, if_false); | 
|  4343     __ JumpIfRoot(x0, Heap::kNullValueRootIndex, if_true); |  4343     __ JumpIfRoot(x0, Heap::kNullValueRootIndex, if_true); | 
|  4344     STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE); |  4344     STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE); | 
|  4345     __ JumpIfObjectType(x0, x10, x11, FIRST_SPEC_OBJECT_TYPE, if_false, lt); |  4345     __ JumpIfObjectType(x0, x10, x11, FIRST_JS_RECEIVER_TYPE, if_false, lt); | 
|  4346     // Check for callable or undetectable objects => false. |  4346     // Check for callable or undetectable objects => false. | 
|  4347     __ Ldrb(x10, FieldMemOperand(x10, Map::kBitFieldOffset)); |  4347     __ Ldrb(x10, FieldMemOperand(x10, Map::kBitFieldOffset)); | 
|  4348     __ TestAndSplit(x10, (1 << Map::kIsCallable) | (1 << Map::kIsUndetectable), |  4348     __ TestAndSplit(x10, (1 << Map::kIsCallable) | (1 << Map::kIsUndetectable), | 
|  4349                     if_true, if_false, fall_through); |  4349                     if_true, if_false, fall_through); | 
|  4350 // clang-format off |  4350 // clang-format off | 
|  4351 #define SIMD128_TYPE(TYPE, Type, type, lane_count, lane_type)   \ |  4351 #define SIMD128_TYPE(TYPE, Type, type, lane_count, lane_type)   \ | 
|  4352   } else if (String::Equals(check, factory->type##_string())) { \ |  4352   } else if (String::Equals(check, factory->type##_string())) { \ | 
|  4353     ASM_LOCATION("FullCodeGenerator::EmitLiteralCompareTypeof " \ |  4353     ASM_LOCATION("FullCodeGenerator::EmitLiteralCompareTypeof " \ | 
|  4354                  #type "_string");                              \ |  4354                  #type "_string");                              \ | 
|  4355     __ JumpIfSmi(x0, if_true);                                  \ |  4355     __ JumpIfSmi(x0, if_true);                                  \ | 
| (...skipping 626 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  4982   } |  4982   } | 
|  4983  |  4983  | 
|  4984   return INTERRUPT; |  4984   return INTERRUPT; | 
|  4985 } |  4985 } | 
|  4986  |  4986  | 
|  4987  |  4987  | 
|  4988 }  // namespace internal |  4988 }  // namespace internal | 
|  4989 }  // namespace v8 |  4989 }  // namespace v8 | 
|  4990  |  4990  | 
|  4991 #endif  // V8_TARGET_ARCH_ARM64 |  4991 #endif  // V8_TARGET_ARCH_ARM64 | 
| OLD | NEW |