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 1752 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1763 RawFunction::Kind kind() const { | 1763 RawFunction::Kind kind() const { |
1764 return KindBits::decode(raw_ptr()->kind_tag_); | 1764 return KindBits::decode(raw_ptr()->kind_tag_); |
1765 } | 1765 } |
1766 | 1766 |
1767 RawFunction::AsyncModifier modifier() const { | 1767 RawFunction::AsyncModifier modifier() const { |
1768 return ModifierBits::decode(raw_ptr()->kind_tag_); | 1768 return ModifierBits::decode(raw_ptr()->kind_tag_); |
1769 } | 1769 } |
1770 | 1770 |
1771 static const char* KindToCString(RawFunction::Kind kind); | 1771 static const char* KindToCString(RawFunction::Kind kind); |
1772 | 1772 |
1773 bool is_static() const { return StaticBit::decode(raw_ptr()->kind_tag_); } | |
1774 bool is_const() const { return ConstBit::decode(raw_ptr()->kind_tag_); } | |
1775 bool is_external() const { return ExternalBit::decode(raw_ptr()->kind_tag_); } | |
1776 bool IsConstructor() const { | 1773 bool IsConstructor() const { |
1777 return (kind() == RawFunction::kConstructor) && !is_static(); | 1774 return (kind() == RawFunction::kConstructor) && !is_static(); |
1778 } | 1775 } |
1779 bool IsImplicitConstructor() const; | 1776 bool IsImplicitConstructor() const; |
1780 bool IsFactory() const { | 1777 bool IsFactory() const { |
1781 return (kind() == RawFunction::kConstructor) && is_static(); | 1778 return (kind() == RawFunction::kConstructor) && is_static(); |
1782 } | 1779 } |
1783 bool IsDynamicFunction() const { | 1780 bool IsDynamicFunction() const { |
1784 if (is_static() || is_abstract()) { | 1781 if (is_static() || is_abstract()) { |
1785 return false; | 1782 return false; |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1907 } | 1904 } |
1908 StoreNonPointer(&raw_ptr()->optimized_call_site_count_, | 1905 StoreNonPointer(&raw_ptr()->optimized_call_site_count_, |
1909 static_cast<uint16_t>(value)); | 1906 static_cast<uint16_t>(value)); |
1910 } | 1907 } |
1911 | 1908 |
1912 bool IsOptimizable() const; | 1909 bool IsOptimizable() const; |
1913 bool IsNativeAutoSetupScope() const; | 1910 bool IsNativeAutoSetupScope() const; |
1914 void SetIsOptimizable(bool value) const; | 1911 void SetIsOptimizable(bool value) const; |
1915 void SetIsNativeAutoSetupScope(bool value) const; | 1912 void SetIsNativeAutoSetupScope(bool value) const; |
1916 | 1913 |
1917 bool is_async_closure() const { | 1914 bool CanBeInlined() const; |
1918 return AsyncClosureBit::decode(raw_ptr()->kind_tag_); | |
1919 } | |
1920 void set_is_async_closure(bool value) const; | |
1921 | |
1922 bool is_native() const { return NativeBit::decode(raw_ptr()->kind_tag_); } | |
1923 void set_is_native(bool value) const; | |
1924 | |
1925 bool is_abstract() const { return AbstractBit::decode(raw_ptr()->kind_tag_); } | |
1926 void set_is_abstract(bool value) const; | |
1927 | |
1928 bool IsInlineable() const; | |
1929 void set_is_inlinable(bool value) const; | |
1930 | |
1931 bool is_visible() const { | |
1932 return VisibleBit::decode(raw_ptr()->kind_tag_); | |
1933 } | |
1934 void set_is_visible(bool value) const; | |
1935 | |
1936 bool is_intrinsic() const { | |
1937 return IntrinsicBit::decode(raw_ptr()->kind_tag_); | |
1938 } | |
1939 void set_is_intrinsic(bool value) const; | |
1940 | 1915 |
1941 MethodRecognizer::Kind recognized_kind() const { | 1916 MethodRecognizer::Kind recognized_kind() const { |
1942 return RecognizedBits::decode(raw_ptr()->kind_tag_); | 1917 return RecognizedBits::decode(raw_ptr()->kind_tag_); |
1943 } | 1918 } |
1944 void set_recognized_kind(MethodRecognizer::Kind value) const; | 1919 void set_recognized_kind(MethodRecognizer::Kind value) const; |
1945 | 1920 |
1946 bool IsRecognized() const { | 1921 bool IsRecognized() const { |
1947 return recognized_kind() != MethodRecognizer::kUnknown; | 1922 return recognized_kind() != MethodRecognizer::kUnknown; |
1948 } | 1923 } |
1949 | 1924 |
1950 bool is_redirecting() const { | |
1951 return RedirectingBit::decode(raw_ptr()->kind_tag_); | |
1952 } | |
1953 void set_is_redirecting(bool value) const; | |
1954 | |
1955 bool allows_hoisting_check_class() const { | |
1956 return AllowsHoistingCheckClassBit::decode(raw_ptr()->kind_tag_); | |
1957 } | |
1958 void set_allows_hoisting_check_class(bool value) const; | |
1959 | |
1960 bool always_inline() const { | |
1961 return AlwaysInlineBit::decode(raw_ptr()->kind_tag_); | |
1962 } | |
1963 void set_always_inline(bool value) const { | |
1964 set_kind_tag(AlwaysInlineBit::update(value, raw_ptr()->kind_tag_)); | |
1965 } | |
1966 | |
1967 bool is_polymorphic_target() const { | |
1968 return PolymorphicTargetBit::decode(raw_ptr()->kind_tag_); | |
1969 } | |
1970 void set_is_polymorphic_target(bool value) const { | |
1971 set_kind_tag(PolymorphicTargetBit::update(value, raw_ptr()->kind_tag_)); | |
1972 } | |
1973 | |
1974 | |
1975 bool HasOptimizedCode() const; | 1925 bool HasOptimizedCode() const; |
1976 | 1926 |
1977 // Returns true if the argument counts are valid for calling this function. | 1927 // Returns true if the argument counts are valid for calling this function. |
1978 // Otherwise, it returns false and the reason (if error_message is not NULL). | 1928 // Otherwise, it returns false and the reason (if error_message is not NULL). |
1979 bool AreValidArgumentCounts(intptr_t num_arguments, | 1929 bool AreValidArgumentCounts(intptr_t num_arguments, |
1980 intptr_t num_named_arguments, | 1930 intptr_t num_named_arguments, |
1981 String* error_message) const; | 1931 String* error_message) const; |
1982 | 1932 |
1983 // Returns true if the total argument count and the names of optional | 1933 // Returns true if the total argument count and the names of optional |
1984 // arguments are valid for calling this function. | 1934 // arguments are valid for calling this function. |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2134 | 2084 |
2135 RawArray* ic_data_array() const; | 2085 RawArray* ic_data_array() const; |
2136 void ClearICData() const; | 2086 void ClearICData() const; |
2137 | 2087 |
2138 static const int kCtorPhaseInit = 1 << 0; | 2088 static const int kCtorPhaseInit = 1 << 0; |
2139 static const int kCtorPhaseBody = 1 << 1; | 2089 static const int kCtorPhaseBody = 1 << 1; |
2140 static const int kCtorPhaseAll = (kCtorPhaseInit | kCtorPhaseBody); | 2090 static const int kCtorPhaseAll = (kCtorPhaseInit | kCtorPhaseBody); |
2141 | 2091 |
2142 void set_modifier(RawFunction::AsyncModifier value) const; | 2092 void set_modifier(RawFunction::AsyncModifier value) const; |
2143 | 2093 |
| 2094 #define FOR_EACH_FUNCTION_KIND_BIT(V) \ |
| 2095 V(Static, is_static) \ |
| 2096 V(Const, is_const) \ |
| 2097 V(Abstract, is_abstract) \ |
| 2098 V(Visible, is_visible) \ |
| 2099 V(Optimizable, is_optimizable) \ |
| 2100 V(Inlinable, is_inlinable) \ |
| 2101 V(Intrinsic, is_intrinsic) \ |
| 2102 V(Native, is_native) \ |
| 2103 V(Redirecting, is_redirecting) \ |
| 2104 V(External, is_external) \ |
| 2105 V(AllowsHoistingCheckClass, allows_hoisting_check_class) \ |
| 2106 V(AllowsBoundsCheckGeneralization, allows_bounds_check_generalization) \ |
| 2107 V(AsyncClosure, is_async_closure) \ |
| 2108 V(AlwaysInline, always_inline) \ |
| 2109 V(PolymorphicTarget, is_polymorphic_target) \ |
| 2110 |
| 2111 #define DEFINE_ACCESSORS(name, accessor_name) \ |
| 2112 void set_##accessor_name(bool value) const { \ |
| 2113 set_kind_tag(name##Bit::update(value, raw_ptr()->kind_tag_)); \ |
| 2114 } \ |
| 2115 bool accessor_name() const { \ |
| 2116 return name##Bit::decode(raw_ptr()->kind_tag_); \ |
| 2117 } |
| 2118 FOR_EACH_FUNCTION_KIND_BIT(DEFINE_ACCESSORS) |
| 2119 #undef DEFINE_ACCESSORS |
| 2120 |
2144 private: | 2121 private: |
2145 void set_ic_data_array(const Array& value) const; | 2122 void set_ic_data_array(const Array& value) const; |
2146 | 2123 |
2147 enum KindTagBits { | 2124 enum KindTagBits { |
2148 kKindTagPos = 0, | 2125 kKindTagPos = 0, |
2149 kKindTagSize = 4, | 2126 kKindTagSize = 4, |
2150 kRecognizedTagPos = kKindTagPos + kKindTagSize, | 2127 kRecognizedTagPos = kKindTagPos + kKindTagSize, |
2151 kRecognizedTagSize = 8, | 2128 kRecognizedTagSize = 8, |
| 2129 kModifierPos = kRecognizedTagPos + kRecognizedTagSize, |
2152 // Single bit sized fields start here. | 2130 // Single bit sized fields start here. |
2153 kStaticBit = kRecognizedTagPos + kRecognizedTagSize, | 2131 #define DECLARE_BIT(name, _) k##name##Bit, |
2154 kConstBit, | 2132 FOR_EACH_FUNCTION_KIND_BIT(DECLARE_BIT) |
2155 kAbstractBit, | 2133 #undef DECLARE_BIT |
2156 kVisibleBit, | |
2157 kOptimizableBit, | |
2158 kInlinableBit, | |
2159 kIntrinsicBit, | |
2160 kNativeBit, | |
2161 kRedirectingBit, | |
2162 kExternalBit, | |
2163 kAllowsHoistingCheckClassBit, | |
2164 kModifierPos, | |
2165 kAsyncClosureBit, | |
2166 kAlwaysInlineBit, | |
2167 kPolymorphicTargetBit, | |
2168 kNumTagBits | 2134 kNumTagBits |
2169 }; | 2135 }; |
2170 | 2136 |
2171 COMPILE_ASSERT( | 2137 COMPILE_ASSERT( |
2172 MethodRecognizer::kNumRecognizedMethods < (1 << kRecognizedTagSize)); | 2138 MethodRecognizer::kNumRecognizedMethods < (1 << kRecognizedTagSize)); |
2173 COMPILE_ASSERT( | 2139 COMPILE_ASSERT( |
2174 kNumTagBits <= | 2140 kNumTagBits <= |
2175 (kBitsPerByte * sizeof(static_cast<RawFunction*>(0)->kind_tag_))); | 2141 (kBitsPerByte * sizeof(static_cast<RawFunction*>(0)->kind_tag_))); |
2176 | 2142 |
2177 class KindBits : | 2143 class KindBits : |
2178 public BitField<RawFunction::Kind, kKindTagPos, kKindTagSize> {}; // NOLINT | 2144 public BitField<RawFunction::Kind, kKindTagPos, kKindTagSize> {}; // NOLINT |
2179 class RecognizedBits : public BitField<MethodRecognizer::Kind, | 2145 class RecognizedBits : public BitField<MethodRecognizer::Kind, |
2180 kRecognizedTagPos, | 2146 kRecognizedTagPos, |
2181 kRecognizedTagSize> {}; | 2147 kRecognizedTagSize> {}; |
2182 class StaticBit : public BitField<bool, kStaticBit, 1> {}; | |
2183 class ConstBit : public BitField<bool, kConstBit, 1> {}; | |
2184 class AbstractBit : public BitField<bool, kAbstractBit, 1> {}; | |
2185 class VisibleBit : public BitField<bool, kVisibleBit, 1> {}; | |
2186 class OptimizableBit : public BitField<bool, kOptimizableBit, 1> {}; | |
2187 class InlinableBit : public BitField<bool, kInlinableBit, 1> {}; | |
2188 class IntrinsicBit : public BitField<bool, kIntrinsicBit, 1> {}; | |
2189 class NativeBit : public BitField<bool, kNativeBit, 1> {}; | |
2190 class ExternalBit : public BitField<bool, kExternalBit, 1> {}; | |
2191 class RedirectingBit : public BitField<bool, kRedirectingBit, 1> {}; | |
2192 class AllowsHoistingCheckClassBit : | |
2193 public BitField<bool, kAllowsHoistingCheckClassBit, 1> {}; // NOLINT | |
2194 class ModifierBits : | 2148 class ModifierBits : |
2195 public BitField<RawFunction::AsyncModifier, kModifierPos, 1> {}; // NOLIN
T | 2149 public BitField<RawFunction::AsyncModifier, kModifierPos, 1> {}; // NOLIN
T |
2196 class AsyncClosureBit : public BitField<bool, kAsyncClosureBit, 1> {}; | 2150 |
2197 class AlwaysInlineBit : public BitField<bool, kAlwaysInlineBit, 1> {}; | 2151 #define DEFINE_BIT(name, _) \ |
2198 class PolymorphicTargetBit : | 2152 class name##Bit : public BitField<bool, k##name##Bit, 1> {}; |
2199 public BitField<bool, kPolymorphicTargetBit, 1> {}; // NOLINT | 2153 FOR_EACH_FUNCTION_KIND_BIT(DEFINE_BIT) |
| 2154 #undef DEFINE_BIT |
2200 | 2155 |
2201 void set_name(const String& value) const; | 2156 void set_name(const String& value) const; |
2202 void set_kind(RawFunction::Kind value) const; | 2157 void set_kind(RawFunction::Kind value) const; |
2203 void set_is_static(bool value) const; | |
2204 void set_is_const(bool value) const; | |
2205 void set_is_external(bool value) const; | |
2206 void set_parent_function(const Function& value) const; | 2158 void set_parent_function(const Function& value) const; |
2207 void set_owner(const Object& value) const; | 2159 void set_owner(const Object& value) const; |
2208 RawFunction* implicit_closure_function() const; | 2160 RawFunction* implicit_closure_function() const; |
2209 void set_implicit_closure_function(const Function& value) const; | 2161 void set_implicit_closure_function(const Function& value) const; |
2210 RawInstance* implicit_static_closure() const; | 2162 RawInstance* implicit_static_closure() const; |
2211 void set_implicit_static_closure(const Instance& closure) const; | 2163 void set_implicit_static_closure(const Instance& closure) const; |
2212 RawScript* eval_script() const; | 2164 RawScript* eval_script() const; |
2213 void set_eval_script(const Script& value) const; | 2165 void set_eval_script(const Script& value) const; |
2214 void set_num_optional_parameters(intptr_t value) const; // Encoded value. | 2166 void set_num_optional_parameters(intptr_t value) const; // Encoded value. |
2215 void set_kind_tag(intptr_t value) const; | 2167 void set_kind_tag(intptr_t value) const; |
2216 void set_data(const Object& value) const; | 2168 void set_data(const Object& value) const; |
2217 bool is_optimizable() const { | |
2218 return OptimizableBit::decode(raw_ptr()->kind_tag_); | |
2219 } | |
2220 void set_is_optimizable(bool value) const; | |
2221 | 2169 |
2222 static RawFunction* New(); | 2170 static RawFunction* New(); |
2223 | 2171 |
2224 void BuildSignatureParameters(bool instantiate, | 2172 void BuildSignatureParameters(bool instantiate, |
2225 NameVisibility name_visibility, | 2173 NameVisibility name_visibility, |
2226 const TypeArguments& instantiator, | 2174 const TypeArguments& instantiator, |
2227 const GrowableObjectArray& pieces) const; | 2175 const GrowableObjectArray& pieces) const; |
2228 RawString* BuildSignature(bool instantiate, | 2176 RawString* BuildSignature(bool instantiate, |
2229 NameVisibility name_visibility, | 2177 NameVisibility name_visibility, |
2230 const TypeArguments& instantiator) const; | 2178 const TypeArguments& instantiator) const; |
(...skipping 1291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3522 V(ShiftMintOp) \ | 3470 V(ShiftMintOp) \ |
3523 V(BinaryDoubleOp) \ | 3471 V(BinaryDoubleOp) \ |
3524 V(InstanceSetter) \ | 3472 V(InstanceSetter) \ |
3525 V(Equality) \ | 3473 V(Equality) \ |
3526 V(RelationalOp) \ | 3474 V(RelationalOp) \ |
3527 V(EqualityClassCheck) \ | 3475 V(EqualityClassCheck) \ |
3528 V(NoTypeFeedback) \ | 3476 V(NoTypeFeedback) \ |
3529 V(UnaryOp) \ | 3477 V(UnaryOp) \ |
3530 V(UnboxInteger) \ | 3478 V(UnboxInteger) \ |
3531 V(CheckClass) \ | 3479 V(CheckClass) \ |
3532 V(HoistedCheckClass) \ | |
3533 V(CheckSmi) \ | 3480 V(CheckSmi) \ |
3534 V(CheckArrayBound) \ | 3481 V(CheckArrayBound) \ |
3535 V(AtCall) \ | 3482 V(AtCall) \ |
3536 V(DoubleToSmi) \ | 3483 V(DoubleToSmi) \ |
3537 V(Int32Load) \ | 3484 V(Int32Load) \ |
3538 V(Uint32Load) \ | 3485 V(Uint32Load) \ |
3539 V(GuardField) \ | 3486 V(GuardField) \ |
3540 V(TestCids) \ | 3487 V(TestCids) \ |
3541 V(NumReasons) \ | 3488 V(NumReasons) \ |
3542 | 3489 |
3543 enum DeoptReasonId { | 3490 enum DeoptReasonId { |
3544 #define DEFINE_ENUM_LIST(name) kDeopt##name, | 3491 #define DEFINE_ENUM_LIST(name) kDeopt##name, |
3545 DEOPT_REASONS(DEFINE_ENUM_LIST) | 3492 DEOPT_REASONS(DEFINE_ENUM_LIST) |
3546 #undef DEFINE_ENUM_LIST | 3493 #undef DEFINE_ENUM_LIST |
3547 }; | 3494 }; |
3548 | 3495 |
| 3496 enum DeoptFlags { |
| 3497 // Deoptimization is caused by an optimistically hoisted instruction. |
| 3498 kHoisted = 1 << 0, |
| 3499 |
| 3500 // Deoptimization is caused by an optimistically generalized bounds check. |
| 3501 kGeneralized = 1 << 1 |
| 3502 }; |
| 3503 |
3549 bool HasDeoptReasons() const { return DeoptReasons() != 0; } | 3504 bool HasDeoptReasons() const { return DeoptReasons() != 0; } |
3550 uint32_t DeoptReasons() const; | 3505 uint32_t DeoptReasons() const; |
3551 void SetDeoptReasons(uint32_t reasons) const; | 3506 void SetDeoptReasons(uint32_t reasons) const; |
3552 | 3507 |
3553 bool HasDeoptReason(ICData::DeoptReasonId reason) const; | 3508 bool HasDeoptReason(ICData::DeoptReasonId reason) const; |
3554 void AddDeoptReason(ICData::DeoptReasonId reason) const; | 3509 void AddDeoptReason(ICData::DeoptReasonId reason) const; |
3555 | 3510 |
3556 bool IssuedJSWarning() const; | 3511 bool IssuedJSWarning() const; |
3557 void SetIssuedJSWarning() const; | 3512 void SetIssuedJSWarning() const; |
3558 | 3513 |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3782 kSCallTableFunctionEntry = 1, | 3737 kSCallTableFunctionEntry = 1, |
3783 kSCallTableCodeEntry = 2, | 3738 kSCallTableCodeEntry = 2, |
3784 kSCallTableEntryLength = 3, | 3739 kSCallTableEntryLength = 3, |
3785 }; | 3740 }; |
3786 | 3741 |
3787 void set_static_calls_target_table(const Array& value) const; | 3742 void set_static_calls_target_table(const Array& value) const; |
3788 RawArray* static_calls_target_table() const { | 3743 RawArray* static_calls_target_table() const { |
3789 return raw_ptr()->static_calls_target_table_; | 3744 return raw_ptr()->static_calls_target_table_; |
3790 } | 3745 } |
3791 | 3746 |
3792 RawDeoptInfo* GetDeoptInfoAtPc( | 3747 RawDeoptInfo* GetDeoptInfoAtPc(uword pc, |
3793 uword pc, ICData::DeoptReasonId* deopt_reason) const; | 3748 ICData::DeoptReasonId* deopt_reason, |
| 3749 uint32_t* deopt_flags) const; |
3794 | 3750 |
3795 // Returns null if there is no static call at 'pc'. | 3751 // Returns null if there is no static call at 'pc'. |
3796 RawFunction* GetStaticCallTargetFunctionAt(uword pc) const; | 3752 RawFunction* GetStaticCallTargetFunctionAt(uword pc) const; |
3797 // Returns null if there is no static call at 'pc'. | 3753 // Returns null if there is no static call at 'pc'. |
3798 RawCode* GetStaticCallTargetCodeAt(uword pc) const; | 3754 RawCode* GetStaticCallTargetCodeAt(uword pc) const; |
3799 // Aborts if there is no static call at 'pc'. | 3755 // Aborts if there is no static call at 'pc'. |
3800 void SetStaticCallTargetCodeAt(uword pc, const Code& code) const; | 3756 void SetStaticCallTargetCodeAt(uword pc, const Code& code) const; |
3801 void SetStubCallTargetCodeAt(uword pc, const Code& code) const; | 3757 void SetStubCallTargetCodeAt(uword pc, const Code& code) const; |
3802 | 3758 |
3803 void Disassemble(DisassemblyFormatter* formatter = NULL) const; | 3759 void Disassemble(DisassemblyFormatter* formatter = NULL) const; |
(...skipping 3709 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7513 | 7469 |
7514 | 7470 |
7515 RawObject* MegamorphicCache::GetTargetFunction(const Array& array, | 7471 RawObject* MegamorphicCache::GetTargetFunction(const Array& array, |
7516 intptr_t index) { | 7472 intptr_t index) { |
7517 return array.At((index * kEntryLength) + kTargetFunctionIndex); | 7473 return array.At((index * kEntryLength) + kTargetFunctionIndex); |
7518 } | 7474 } |
7519 | 7475 |
7520 } // namespace dart | 7476 } // namespace dart |
7521 | 7477 |
7522 #endif // VM_OBJECT_H_ | 7478 #endif // VM_OBJECT_H_ |
OLD | NEW |