| OLD | NEW |
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include <setjmp.h> // NOLINT | 5 #include <setjmp.h> // NOLINT |
| 6 #include <stdlib.h> | 6 #include <stdlib.h> |
| 7 | 7 |
| 8 #include "vm/globals.h" | 8 #include "vm/globals.h" |
| 9 #if defined(TARGET_ARCH_DBC) | 9 #if defined(TARGET_ARCH_DBC) |
| 10 | 10 |
| (...skipping 1569 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1580 } | 1580 } |
| 1581 #else | 1581 #else |
| 1582 // There should be no debug breaks in product mode. | 1582 // There should be no debug breaks in product mode. |
| 1583 UNREACHABLE(); | 1583 UNREACHABLE(); |
| 1584 #endif | 1584 #endif |
| 1585 DISPATCH(); | 1585 DISPATCH(); |
| 1586 } | 1586 } |
| 1587 | 1587 |
| 1588 { | 1588 { |
| 1589 BYTECODE(InstantiateType, A_D); | 1589 BYTECODE(InstantiateType, A_D); |
| 1590 // Stack: instantiator type args, function type args |
| 1590 RawObject* type = LOAD_CONSTANT(rD); | 1591 RawObject* type = LOAD_CONSTANT(rD); |
| 1591 SP[1] = type; | 1592 SP[1] = type; |
| 1592 SP[2] = SP[0]; | 1593 SP[2] = SP[-1]; |
| 1593 SP[0] = null_value; | 1594 SP[3] = SP[0]; |
| 1594 Exit(thread, FP, SP + 3, pc); | 1595 Exit(thread, FP, SP + 4, pc); |
| 1595 { | 1596 { |
| 1596 NativeArguments args(thread, 2, SP + 1, SP); | 1597 NativeArguments args(thread, 3, SP + 1, SP - 1); |
| 1597 INVOKE_RUNTIME(DRT_InstantiateType, args); | 1598 INVOKE_RUNTIME(DRT_InstantiateType, args); |
| 1598 } | 1599 } |
| 1600 SP -= 1; |
| 1599 DISPATCH(); | 1601 DISPATCH(); |
| 1600 } | 1602 } |
| 1601 | 1603 |
| 1602 { | 1604 { |
| 1603 BYTECODE(InstantiateTypeArgumentsTOS, A_D); | 1605 BYTECODE(InstantiateTypeArgumentsTOS, A_D); |
| 1606 // Stack: instantiator type args, function type args |
| 1604 RawTypeArguments* type_arguments = | 1607 RawTypeArguments* type_arguments = |
| 1605 static_cast<RawTypeArguments*>(LOAD_CONSTANT(rD)); | 1608 static_cast<RawTypeArguments*>(LOAD_CONSTANT(rD)); |
| 1606 | 1609 |
| 1607 RawObject* instantiator = SP[0]; | 1610 RawObject* instantiator_type_args = SP[-1]; |
| 1608 // If the instantiator is null and if the type argument vector | 1611 RawObject* function_type_args = SP[0]; |
| 1612 // If both instantiators are null and if the type argument vector |
| 1609 // instantiated from null becomes a vector of dynamic, then use null as | 1613 // instantiated from null becomes a vector of dynamic, then use null as |
| 1610 // the type arguments. | 1614 // the type arguments. |
| 1611 if (rA == 0 || null_value != instantiator) { | 1615 if ((rA == 0) || (null_value != instantiator_type_args) || |
| 1616 (null_value != function_type_args)) { |
| 1612 // First lookup in the cache. | 1617 // First lookup in the cache. |
| 1613 RawArray* instantiations = type_arguments->ptr()->instantiations_; | 1618 RawArray* instantiations = type_arguments->ptr()->instantiations_; |
| 1614 for (intptr_t i = 0; | 1619 for (intptr_t i = 0; |
| 1615 instantiations->ptr()->data()[i] != NULL; // kNoInstantiator | 1620 instantiations->ptr()->data()[i] != NULL; // kNoInstantiator |
| 1616 i += 2) { | 1621 i += 3) { // kInstantiationSizeInWords |
| 1617 if (instantiations->ptr()->data()[i] == instantiator) { | 1622 if ((instantiations->ptr()->data()[i] == instantiator_type_args) && |
| 1623 (instantiations->ptr()->data()[i + 1] == function_type_args)) { |
| 1618 // Found in the cache. | 1624 // Found in the cache. |
| 1619 SP[0] = instantiations->ptr()->data()[i + 1]; | 1625 SP[-1] = instantiations->ptr()->data()[i + 2]; |
| 1620 goto InstantiateTypeArgumentsTOSDone; | 1626 goto InstantiateTypeArgumentsTOSDone; |
| 1621 } | 1627 } |
| 1622 } | 1628 } |
| 1623 | 1629 |
| 1624 // Cache lookup failed, call runtime. | 1630 // Cache lookup failed, call runtime. |
| 1625 SP[1] = type_arguments; | 1631 SP[1] = type_arguments; |
| 1626 SP[2] = instantiator; | 1632 SP[2] = instantiator_type_args; |
| 1633 SP[3] = function_type_args; |
| 1627 | 1634 |
| 1628 Exit(thread, FP, SP + 3, pc); | 1635 Exit(thread, FP, SP + 4, pc); |
| 1629 NativeArguments args(thread, 2, SP + 1, SP); | 1636 NativeArguments args(thread, 3, SP + 1, SP - 1); |
| 1630 INVOKE_RUNTIME(DRT_InstantiateTypeArguments, args); | 1637 INVOKE_RUNTIME(DRT_InstantiateTypeArguments, args); |
| 1631 } | 1638 } |
| 1632 | 1639 |
| 1633 InstantiateTypeArgumentsTOSDone: | 1640 InstantiateTypeArgumentsTOSDone: |
| 1641 SP -= 1; |
| 1634 DISPATCH(); | 1642 DISPATCH(); |
| 1635 } | 1643 } |
| 1636 | 1644 |
| 1637 { | 1645 { |
| 1638 BYTECODE(Throw, A); | 1646 BYTECODE(Throw, A); |
| 1639 { | 1647 { |
| 1640 SP[1] = 0; // Space for result. | 1648 SP[1] = 0; // Space for result. |
| 1641 Exit(thread, FP, SP + 2, pc); | 1649 Exit(thread, FP, SP + 2, pc); |
| 1642 if (rA == 0) { // Throw | 1650 if (rA == 0) { // Throw |
| 1643 NativeArguments args(thread, 1, SP, SP + 1); | 1651 NativeArguments args(thread, 1, SP, SP + 1); |
| (...skipping 1338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2982 SP[1] = SP[-0]; // Length. | 2990 SP[1] = SP[-0]; // Length. |
| 2983 SP[2] = SP[-1]; // Type. | 2991 SP[2] = SP[-1]; // Type. |
| 2984 Exit(thread, FP, SP + 3, pc); | 2992 Exit(thread, FP, SP + 3, pc); |
| 2985 NativeArguments args(thread, 2, SP + 1, SP - 1); | 2993 NativeArguments args(thread, 2, SP + 1, SP - 1); |
| 2986 INVOKE_RUNTIME(DRT_AllocateArray, args); | 2994 INVOKE_RUNTIME(DRT_AllocateArray, args); |
| 2987 SP -= 1; | 2995 SP -= 1; |
| 2988 DISPATCH(); | 2996 DISPATCH(); |
| 2989 } | 2997 } |
| 2990 | 2998 |
| 2991 { | 2999 { |
| 2992 BYTECODE(InstanceOf, 0); // Stack: instance, type args, type, cache | 3000 BYTECODE(InstanceOf, 0); |
| 2993 RawInstance* instance = static_cast<RawInstance*>(SP[-3]); | 3001 // Stack: instance, instantiator type args, function type args, type, cache |
| 3002 RawInstance* instance = static_cast<RawInstance*>(SP[-4]); |
| 2994 RawTypeArguments* instantiator_type_arguments = | 3003 RawTypeArguments* instantiator_type_arguments = |
| 3004 static_cast<RawTypeArguments*>(SP[-3]); |
| 3005 RawTypeArguments* function_type_arguments = |
| 2995 static_cast<RawTypeArguments*>(SP[-2]); | 3006 static_cast<RawTypeArguments*>(SP[-2]); |
| 2996 RawAbstractType* type = static_cast<RawAbstractType*>(SP[-1]); | 3007 RawAbstractType* type = static_cast<RawAbstractType*>(SP[-1]); |
| 2997 RawSubtypeTestCache* cache = static_cast<RawSubtypeTestCache*>(SP[0]); | 3008 RawSubtypeTestCache* cache = static_cast<RawSubtypeTestCache*>(SP[0]); |
| 2998 | 3009 |
| 2999 if (cache != null_value) { | 3010 if (cache != null_value) { |
| 3000 const intptr_t cid = SimulatorHelpers::GetClassId(instance); | 3011 const intptr_t cid = SimulatorHelpers::GetClassId(instance); |
| 3001 | 3012 |
| 3002 RawTypeArguments* instance_type_arguments = | 3013 RawTypeArguments* instance_type_arguments = |
| 3003 static_cast<RawTypeArguments*>(null_value); | 3014 static_cast<RawTypeArguments*>(null_value); |
| 3004 RawObject* instance_cid_or_function; | 3015 RawObject* instance_cid_or_function; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 3020 } | 3031 } |
| 3021 | 3032 |
| 3022 for (RawObject** entries = cache->ptr()->cache_->ptr()->data(); | 3033 for (RawObject** entries = cache->ptr()->cache_->ptr()->data(); |
| 3023 entries[0] != null_value; | 3034 entries[0] != null_value; |
| 3024 entries += SubtypeTestCache::kTestEntryLength) { | 3035 entries += SubtypeTestCache::kTestEntryLength) { |
| 3025 if ((entries[SubtypeTestCache::kInstanceClassIdOrFunction] == | 3036 if ((entries[SubtypeTestCache::kInstanceClassIdOrFunction] == |
| 3026 instance_cid_or_function) && | 3037 instance_cid_or_function) && |
| 3027 (entries[SubtypeTestCache::kInstanceTypeArguments] == | 3038 (entries[SubtypeTestCache::kInstanceTypeArguments] == |
| 3028 instance_type_arguments) && | 3039 instance_type_arguments) && |
| 3029 (entries[SubtypeTestCache::kInstantiatorTypeArguments] == | 3040 (entries[SubtypeTestCache::kInstantiatorTypeArguments] == |
| 3030 instantiator_type_arguments)) { | 3041 instantiator_type_arguments) && |
| 3031 SP[-3] = entries[SubtypeTestCache::kTestResult]; | 3042 (entries[SubtypeTestCache::kFunctionTypeArguments] == |
| 3043 function_type_arguments)) { |
| 3044 SP[-4] = entries[SubtypeTestCache::kTestResult]; |
| 3032 goto InstanceOfOk; | 3045 goto InstanceOfOk; |
| 3033 } | 3046 } |
| 3034 } | 3047 } |
| 3035 } | 3048 } |
| 3036 | 3049 |
| 3037 // clang-format off | 3050 // clang-format off |
| 3038 InstanceOfCallRuntime: | 3051 InstanceOfCallRuntime: |
| 3039 { | 3052 { |
| 3040 SP[1] = instance; | 3053 SP[1] = instance; |
| 3041 SP[2] = type; | 3054 SP[2] = type; |
| 3042 SP[3] = instantiator_type_arguments; | 3055 SP[3] = instantiator_type_arguments; |
| 3043 SP[4] = cache; | 3056 SP[4] = function_type_arguments; |
| 3044 Exit(thread, FP, SP + 5, pc); | 3057 SP[5] = cache; |
| 3045 NativeArguments native_args(thread, 4, SP + 1, SP - 3); | 3058 Exit(thread, FP, SP + 6, pc); |
| 3059 NativeArguments native_args(thread, 5, SP + 1, SP - 4); |
| 3046 INVOKE_RUNTIME(DRT_Instanceof, native_args); | 3060 INVOKE_RUNTIME(DRT_Instanceof, native_args); |
| 3047 } | 3061 } |
| 3048 // clang-format on | 3062 // clang-format on |
| 3049 | 3063 |
| 3050 InstanceOfOk: | 3064 InstanceOfOk: |
| 3051 SP -= 3; | 3065 SP -= 4; |
| 3052 DISPATCH(); | 3066 DISPATCH(); |
| 3053 } | 3067 } |
| 3054 | 3068 |
| 3055 { | 3069 { |
| 3056 BYTECODE(BadTypeError, 0); // Stack: instance, type args, type, name | 3070 BYTECODE(BadTypeError, 0); |
| 3057 RawObject** args = SP - 3; | 3071 // Stack: instance, instantiator type args, function type args, type, name |
| 3072 RawObject** args = SP - 4; |
| 3058 if (args[0] != null_value) { | 3073 if (args[0] != null_value) { |
| 3059 SP[1] = args[0]; // instance. | 3074 SP[1] = args[0]; // instance. |
| 3060 SP[2] = args[3]; // name. | 3075 SP[2] = args[4]; // name. |
| 3061 SP[3] = args[2]; // type. | 3076 SP[3] = args[3]; // type. |
| 3062 Exit(thread, FP, SP + 4, pc); | 3077 Exit(thread, FP, SP + 4, pc); |
| 3063 NativeArguments native_args(thread, 3, SP + 1, SP - 3); | 3078 NativeArguments native_args(thread, 3, SP + 1, SP - 4); |
| 3064 INVOKE_RUNTIME(DRT_BadTypeError, native_args); | 3079 INVOKE_RUNTIME(DRT_BadTypeError, native_args); |
| 3065 UNREACHABLE(); | 3080 UNREACHABLE(); |
| 3066 } | 3081 } |
| 3067 SP -= 3; | 3082 SP -= 4; |
| 3068 DISPATCH(); | 3083 DISPATCH(); |
| 3069 } | 3084 } |
| 3070 | 3085 |
| 3071 { | 3086 { |
| 3072 BYTECODE(AssertAssignable, A_D); // Stack: instance, type args, type, name | 3087 BYTECODE(AssertAssignable, A_D); |
| 3073 RawObject** args = SP - 3; | 3088 // Stack: instance, instantiator type args, function type args, type, name |
| 3089 RawObject** args = SP - 4; |
| 3074 const bool may_be_smi = (rA == 1); | 3090 const bool may_be_smi = (rA == 1); |
| 3075 const bool is_smi = | 3091 const bool is_smi = |
| 3076 ((reinterpret_cast<intptr_t>(args[0]) & kSmiTagMask) == kSmiTag); | 3092 ((reinterpret_cast<intptr_t>(args[0]) & kSmiTagMask) == kSmiTag); |
| 3077 const bool smi_ok = is_smi && may_be_smi; | 3093 const bool smi_ok = is_smi && may_be_smi; |
| 3078 if (!smi_ok && (args[0] != null_value)) { | 3094 if (!smi_ok && (args[0] != null_value)) { |
| 3079 RawSubtypeTestCache* cache = | 3095 RawSubtypeTestCache* cache = |
| 3080 static_cast<RawSubtypeTestCache*>(LOAD_CONSTANT(rD)); | 3096 static_cast<RawSubtypeTestCache*>(LOAD_CONSTANT(rD)); |
| 3081 if (cache != null_value) { | 3097 if (cache != null_value) { |
| 3082 RawInstance* instance = static_cast<RawInstance*>(args[0]); | 3098 RawInstance* instance = static_cast<RawInstance*>(args[0]); |
| 3083 RawTypeArguments* instantiator_type_arguments = | 3099 RawTypeArguments* instantiator_type_arguments = |
| 3084 static_cast<RawTypeArguments*>(args[1]); | 3100 static_cast<RawTypeArguments*>(args[1]); |
| 3101 RawTypeArguments* function_type_arguments = |
| 3102 static_cast<RawTypeArguments*>(args[2]); |
| 3085 | 3103 |
| 3086 const intptr_t cid = SimulatorHelpers::GetClassId(instance); | 3104 const intptr_t cid = SimulatorHelpers::GetClassId(instance); |
| 3087 | 3105 |
| 3088 RawTypeArguments* instance_type_arguments = | 3106 RawTypeArguments* instance_type_arguments = |
| 3089 static_cast<RawTypeArguments*>(null_value); | 3107 static_cast<RawTypeArguments*>(null_value); |
| 3090 RawObject* instance_cid_or_function; | 3108 RawObject* instance_cid_or_function; |
| 3091 if (cid == kClosureCid) { | 3109 if (cid == kClosureCid) { |
| 3092 RawClosure* closure = static_cast<RawClosure*>(instance); | 3110 RawClosure* closure = static_cast<RawClosure*>(instance); |
| 3093 instance_type_arguments = closure->ptr()->instantiator_; | 3111 instance_type_arguments = closure->ptr()->instantiator_; |
| 3094 instance_cid_or_function = closure->ptr()->function_; | 3112 instance_cid_or_function = closure->ptr()->function_; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 3106 } | 3124 } |
| 3107 | 3125 |
| 3108 for (RawObject** entries = cache->ptr()->cache_->ptr()->data(); | 3126 for (RawObject** entries = cache->ptr()->cache_->ptr()->data(); |
| 3109 entries[0] != null_value; | 3127 entries[0] != null_value; |
| 3110 entries += SubtypeTestCache::kTestEntryLength) { | 3128 entries += SubtypeTestCache::kTestEntryLength) { |
| 3111 if ((entries[SubtypeTestCache::kInstanceClassIdOrFunction] == | 3129 if ((entries[SubtypeTestCache::kInstanceClassIdOrFunction] == |
| 3112 instance_cid_or_function) && | 3130 instance_cid_or_function) && |
| 3113 (entries[SubtypeTestCache::kInstanceTypeArguments] == | 3131 (entries[SubtypeTestCache::kInstanceTypeArguments] == |
| 3114 instance_type_arguments) && | 3132 instance_type_arguments) && |
| 3115 (entries[SubtypeTestCache::kInstantiatorTypeArguments] == | 3133 (entries[SubtypeTestCache::kInstantiatorTypeArguments] == |
| 3116 instantiator_type_arguments)) { | 3134 instantiator_type_arguments) && |
| 3135 (entries[SubtypeTestCache::kFunctionTypeArguments] == |
| 3136 function_type_arguments)) { |
| 3117 if (true_value == entries[SubtypeTestCache::kTestResult]) { | 3137 if (true_value == entries[SubtypeTestCache::kTestResult]) { |
| 3118 goto AssertAssignableOk; | 3138 goto AssertAssignableOk; |
| 3119 } else { | 3139 } else { |
| 3120 break; | 3140 break; |
| 3121 } | 3141 } |
| 3122 } | 3142 } |
| 3123 } | 3143 } |
| 3124 } | 3144 } |
| 3125 | 3145 |
| 3126 AssertAssignableCallRuntime: | 3146 AssertAssignableCallRuntime: |
| 3127 SP[1] = args[0]; // instance | 3147 SP[1] = args[0]; // instance |
| 3128 SP[2] = args[2]; // type | 3148 SP[2] = args[3]; // type |
| 3129 SP[3] = args[1]; // type args | 3149 SP[3] = args[1]; // instantiator type args |
| 3130 SP[4] = args[3]; // name | 3150 SP[4] = args[2]; // function type args |
| 3131 SP[5] = cache; | 3151 SP[5] = args[4]; // name |
| 3132 Exit(thread, FP, SP + 6, pc); | 3152 SP[6] = cache; |
| 3133 NativeArguments native_args(thread, 5, SP + 1, SP - 3); | 3153 Exit(thread, FP, SP + 7, pc); |
| 3154 NativeArguments native_args(thread, 6, SP + 1, SP - 4); |
| 3134 INVOKE_RUNTIME(DRT_TypeCheck, native_args); | 3155 INVOKE_RUNTIME(DRT_TypeCheck, native_args); |
| 3135 } | 3156 } |
| 3136 | 3157 |
| 3137 AssertAssignableOk: | 3158 AssertAssignableOk: |
| 3138 SP -= 3; | 3159 SP -= 4; |
| 3139 DISPATCH(); | 3160 DISPATCH(); |
| 3140 } | 3161 } |
| 3141 | 3162 |
| 3142 { | 3163 { |
| 3143 BYTECODE(AssertBoolean, A); | 3164 BYTECODE(AssertBoolean, A); |
| 3144 RawObject* value = SP[0]; | 3165 RawObject* value = SP[0]; |
| 3145 if (rA) { // Should we perform type check? | 3166 if (rA) { // Should we perform type check? |
| 3146 if ((value == true_value) || (value == false_value)) { | 3167 if ((value == true_value) || (value == false_value)) { |
| 3147 goto AssertBooleanOk; | 3168 goto AssertBooleanOk; |
| 3148 } | 3169 } |
| (...skipping 703 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3852 pc_ = pc; | 3873 pc_ = pc; |
| 3853 } | 3874 } |
| 3854 | 3875 |
| 3855 buf->Longjmp(); | 3876 buf->Longjmp(); |
| 3856 UNREACHABLE(); | 3877 UNREACHABLE(); |
| 3857 } | 3878 } |
| 3858 | 3879 |
| 3859 } // namespace dart | 3880 } // namespace dart |
| 3860 | 3881 |
| 3861 #endif // defined TARGET_ARCH_DBC | 3882 #endif // defined TARGET_ARCH_DBC |
| OLD | NEW |