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 |