| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 #ifndef VM_OBJECT_H_ | 5 #ifndef VM_OBJECT_H_ |
| 6 #define VM_OBJECT_H_ | 6 #define VM_OBJECT_H_ |
| 7 | 7 |
| 8 #include "include/dart_api.h" | 8 #include "include/dart_api.h" |
| 9 #include "platform/assert.h" | 9 #include "platform/assert.h" |
| 10 #include "platform/utils.h" | 10 #include "platform/utils.h" |
| (...skipping 1843 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1854 V(CheckSmi) \ | 1854 V(CheckSmi) \ |
| 1855 V(Unknown) \ | 1855 V(Unknown) \ |
| 1856 V(PolymorphicInstanceCallTestFail) \ | 1856 V(PolymorphicInstanceCallTestFail) \ |
| 1857 V(UnaryMintOp) \ | 1857 V(UnaryMintOp) \ |
| 1858 V(BinaryDoubleOp) \ | 1858 V(BinaryDoubleOp) \ |
| 1859 V(UnaryOp) \ | 1859 V(UnaryOp) \ |
| 1860 V(UnboxInteger) \ | 1860 V(UnboxInteger) \ |
| 1861 V(CheckClass) \ | 1861 V(CheckClass) \ |
| 1862 V(CheckArrayBound) \ | 1862 V(CheckArrayBound) \ |
| 1863 V(AtCall) \ | 1863 V(AtCall) \ |
| 1864 V(Uint32Load) \ | |
| 1865 V(GuardField) \ | 1864 V(GuardField) \ |
| 1866 V(TestCids) \ | 1865 V(TestCids) \ |
| 1867 V(NumReasons) \ | 1866 V(NumReasons) \ |
| 1868 | 1867 |
| 1869 enum DeoptReasonId { | 1868 enum DeoptReasonId { |
| 1870 #define DEFINE_ENUM_LIST(name) kDeopt##name, | 1869 #define DEFINE_ENUM_LIST(name) kDeopt##name, |
| 1871 DEOPT_REASONS(DEFINE_ENUM_LIST) | 1870 DEOPT_REASONS(DEFINE_ENUM_LIST) |
| 1872 #undef DEFINE_ENUM_LIST | 1871 #undef DEFINE_ENUM_LIST |
| 1873 }; | 1872 }; |
| 1874 | 1873 |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2048 } | 2047 } |
| 2049 static intptr_t EntryPointIndexFor(intptr_t num_args) { | 2048 static intptr_t EntryPointIndexFor(intptr_t num_args) { |
| 2050 return (num_args + 1); | 2049 return (num_args + 1); |
| 2051 } | 2050 } |
| 2052 | 2051 |
| 2053 bool IsUsedAt(intptr_t i) const; | 2052 bool IsUsedAt(intptr_t i) const; |
| 2054 | 2053 |
| 2055 void GetUsedCidsForTwoArgs(GrowableArray<intptr_t>* first, | 2054 void GetUsedCidsForTwoArgs(GrowableArray<intptr_t>* first, |
| 2056 GrowableArray<intptr_t>* second) const; | 2055 GrowableArray<intptr_t>* second) const; |
| 2057 | 2056 |
| 2058 // Range feedback tracking functionality. | |
| 2059 | |
| 2060 // For arithmetic operations we store range information for inputs and the | |
| 2061 // result. The goal is to discover: | |
| 2062 // | |
| 2063 // - on 32-bit platforms: | |
| 2064 // - when Mint operation is actually a int32/uint32 operation; | |
| 2065 // - when Smi operation produces non-smi results; | |
| 2066 // | |
| 2067 // - on 64-bit platforms: | |
| 2068 // - when Smi operation is actually int32/uint32 operation; | |
| 2069 // - when Mint operation produces non-smi results; | |
| 2070 // | |
| 2071 enum RangeFeedback { | |
| 2072 kSmiRange, | |
| 2073 kInt32Range, | |
| 2074 kUint32Range, | |
| 2075 kInt64Range | |
| 2076 }; | |
| 2077 | |
| 2078 // We use 4 bits per operand/result feedback. Our lattice allows us to | |
| 2079 // express the following states: | |
| 2080 // | |
| 2081 // - usmi 0000 [used only on 32bit platforms] | |
| 2082 // - smi 0001 | |
| 2083 // - uint31 0010 | |
| 2084 // - int32 0011 | |
| 2085 // - uint32 0100 | |
| 2086 // - int33 x1x1 | |
| 2087 // - int64 1xxx | |
| 2088 // | |
| 2089 // DecodeRangeFeedbackAt() helper maps these states into the RangeFeedback | |
| 2090 // enumeration. | |
| 2091 enum RangeFeedbackLatticeBits { | |
| 2092 kSignedRangeBit = 1 << 0, | |
| 2093 kInt32RangeBit = 1 << 1, | |
| 2094 kUint32RangeBit = 1 << 2, | |
| 2095 kInt64RangeBit = 1 << 3, | |
| 2096 kBitsPerRangeFeedback = 4, | |
| 2097 kRangeFeedbackMask = (1 << kBitsPerRangeFeedback) - 1, | |
| 2098 kRangeFeedbackSlots = 3 | |
| 2099 }; | |
| 2100 | |
| 2101 static bool IsValidRangeFeedbackIndex(intptr_t index) { | |
| 2102 return (0 <= index) && (index < kRangeFeedbackSlots); | |
| 2103 } | |
| 2104 | |
| 2105 static intptr_t RangeFeedbackShift(intptr_t index) { | |
| 2106 return (index * kBitsPerRangeFeedback) + kRangeFeedbackPos; | |
| 2107 } | |
| 2108 | |
| 2109 static const char* RangeFeedbackToString(RangeFeedback feedback) { | |
| 2110 switch (feedback) { | |
| 2111 case kSmiRange: | |
| 2112 return "smi"; | |
| 2113 case kInt32Range: | |
| 2114 return "int32"; | |
| 2115 case kUint32Range: | |
| 2116 return "uint32"; | |
| 2117 case kInt64Range: | |
| 2118 return "int64"; | |
| 2119 default: | |
| 2120 UNREACHABLE(); | |
| 2121 return "?"; | |
| 2122 } | |
| 2123 } | |
| 2124 | |
| 2125 // It is only meaningful to interpret range feedback stored in the ICData | |
| 2126 // when all checks are Mint or Smi. | |
| 2127 bool HasRangeFeedback() const; | |
| 2128 RangeFeedback DecodeRangeFeedbackAt(intptr_t idx) const; | |
| 2129 | |
| 2130 void PrintToJSONArray(const JSONArray& jsarray, | 2057 void PrintToJSONArray(const JSONArray& jsarray, |
| 2131 TokenPosition token_pos, | 2058 TokenPosition token_pos, |
| 2132 bool is_static_call) const; | 2059 bool is_static_call) const; |
| 2133 void PrintToJSONArrayNew(const JSONArray& jsarray, | 2060 void PrintToJSONArrayNew(const JSONArray& jsarray, |
| 2134 TokenPosition token_pos, | 2061 TokenPosition token_pos, |
| 2135 bool is_static_call) const; | 2062 bool is_static_call) const; |
| 2136 | 2063 |
| 2137 // Initialize the preallocated empty ICData entry arrays. | 2064 // Initialize the preallocated empty ICData entry arrays. |
| 2138 static void InitOnce(); | 2065 static void InitOnce(); |
| 2139 | 2066 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 2162 void set_deopt_id(intptr_t value) const; | 2089 void set_deopt_id(intptr_t value) const; |
| 2163 void SetNumArgsTested(intptr_t value) const; | 2090 void SetNumArgsTested(intptr_t value) const; |
| 2164 void set_ic_data_array(const Array& value) const; | 2091 void set_ic_data_array(const Array& value) const; |
| 2165 void set_state_bits(uint32_t bits) const; | 2092 void set_state_bits(uint32_t bits) const; |
| 2166 | 2093 |
| 2167 enum { | 2094 enum { |
| 2168 kNumArgsTestedPos = 0, | 2095 kNumArgsTestedPos = 0, |
| 2169 kNumArgsTestedSize = 2, | 2096 kNumArgsTestedSize = 2, |
| 2170 kDeoptReasonPos = kNumArgsTestedPos + kNumArgsTestedSize, | 2097 kDeoptReasonPos = kNumArgsTestedPos + kNumArgsTestedSize, |
| 2171 kDeoptReasonSize = kLastRecordedDeoptReason + 1, | 2098 kDeoptReasonSize = kLastRecordedDeoptReason + 1, |
| 2172 kRangeFeedbackPos = kDeoptReasonPos + kDeoptReasonSize, | 2099 kStaticCallPos = kDeoptReasonPos + kDeoptReasonSize, |
| 2173 kRangeFeedbackSize = kBitsPerRangeFeedback * kRangeFeedbackSlots, | |
| 2174 kStaticCallPos = kRangeFeedbackPos + kRangeFeedbackSize, | |
| 2175 kStaticCallSize = 1, | 2100 kStaticCallSize = 1, |
| 2176 }; | 2101 }; |
| 2177 | 2102 |
| 2178 class NumArgsTestedBits : public BitField<uint32_t, | 2103 class NumArgsTestedBits : public BitField<uint32_t, |
| 2179 uint32_t, | 2104 uint32_t, |
| 2180 kNumArgsTestedPos, | 2105 kNumArgsTestedPos, |
| 2181 kNumArgsTestedSize> {}; | 2106 kNumArgsTestedSize> {}; |
| 2182 class DeoptReasonBits : public BitField<uint32_t, | 2107 class DeoptReasonBits : public BitField<uint32_t, |
| 2183 uint32_t, | 2108 uint32_t, |
| 2184 ICData::kDeoptReasonPos, | 2109 ICData::kDeoptReasonPos, |
| 2185 ICData::kDeoptReasonSize> {}; | 2110 ICData::kDeoptReasonSize> {}; |
| 2186 class RangeFeedbackBits : public BitField<uint32_t, | |
| 2187 uint32_t, | |
| 2188 ICData::kRangeFeedbackPos, | |
| 2189 ICData::kRangeFeedbackSize> {}; | |
| 2190 | |
| 2191 class StaticCallBit : public BitField<uint32_t, | 2111 class StaticCallBit : public BitField<uint32_t, |
| 2192 bool, | 2112 bool, |
| 2193 ICData::kStaticCallPos, | 2113 ICData::kStaticCallPos, |
| 2194 ICData::kStaticCallSize> {}; | 2114 ICData::kStaticCallSize> {}; |
| 2195 #if defined(DEBUG) | 2115 #if defined(DEBUG) |
| 2196 // Used in asserts to verify that a check is not added twice. | 2116 // Used in asserts to verify that a check is not added twice. |
| 2197 bool HasCheck(const GrowableArray<intptr_t>& cids) const; | 2117 bool HasCheck(const GrowableArray<intptr_t>& cids) const; |
| 2198 #endif // DEBUG | 2118 #endif // DEBUG |
| 2199 | 2119 |
| 2200 intptr_t TestEntryLength() const; | 2120 intptr_t TestEntryLength() const; |
| (...skipping 6530 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8731 | 8651 |
| 8732 inline void TypeArguments::SetHash(intptr_t value) const { | 8652 inline void TypeArguments::SetHash(intptr_t value) const { |
| 8733 // This is only safe because we create a new Smi, which does not cause | 8653 // This is only safe because we create a new Smi, which does not cause |
| 8734 // heap allocation. | 8654 // heap allocation. |
| 8735 StoreSmi(&raw_ptr()->hash_, Smi::New(value)); | 8655 StoreSmi(&raw_ptr()->hash_, Smi::New(value)); |
| 8736 } | 8656 } |
| 8737 | 8657 |
| 8738 } // namespace dart | 8658 } // namespace dart |
| 8739 | 8659 |
| 8740 #endif // VM_OBJECT_H_ | 8660 #endif // VM_OBJECT_H_ |
| OLD | NEW |