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 1196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1207 RawMint* LookupCanonicalMint(Zone* zone, | 1207 RawMint* LookupCanonicalMint(Zone* zone, |
1208 int64_t value, intptr_t* index) const; | 1208 int64_t value, intptr_t* index) const; |
1209 RawBigint* LookupCanonicalBigint(Zone* zone, | 1209 RawBigint* LookupCanonicalBigint(Zone* zone, |
1210 const Bigint& value, intptr_t* index) const; | 1210 const Bigint& value, intptr_t* index) const; |
1211 // The methods above are more efficient than this generic one. | 1211 // The methods above are more efficient than this generic one. |
1212 RawInstance* LookupCanonicalInstance(Zone* zone, | 1212 RawInstance* LookupCanonicalInstance(Zone* zone, |
1213 const Instance& value, | 1213 const Instance& value, |
1214 intptr_t* index) const; | 1214 intptr_t* index) const; |
1215 | 1215 |
1216 void InsertCanonicalConstant(intptr_t index, const Instance& constant) const; | 1216 void InsertCanonicalConstant(intptr_t index, const Instance& constant) const; |
| 1217 void InsertCanonicalNumber(Zone* zone, |
| 1218 intptr_t index, |
| 1219 const Number& constant) const; |
1217 | 1220 |
1218 intptr_t FindCanonicalTypeIndex(const AbstractType& needle) const; | 1221 intptr_t FindCanonicalTypeIndex(const AbstractType& needle) const; |
1219 RawAbstractType* CanonicalTypeFromIndex(intptr_t idx) const; | 1222 RawAbstractType* CanonicalTypeFromIndex(intptr_t idx) const; |
1220 | 1223 |
1221 static intptr_t InstanceSize() { | 1224 static intptr_t InstanceSize() { |
1222 return RoundedAllocationSize(sizeof(RawClass)); | 1225 return RoundedAllocationSize(sizeof(RawClass)); |
1223 } | 1226 } |
1224 | 1227 |
1225 bool is_implemented() const { | 1228 bool is_implemented() const { |
1226 return ImplementedBit::decode(raw_ptr()->state_bits_); | 1229 return ImplementedBit::decode(raw_ptr()->state_bits_); |
(...skipping 3922 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5149 virtual bool CanonicalizeEquals(const Instance& other) const; | 5152 virtual bool CanonicalizeEquals(const Instance& other) const; |
5150 | 5153 |
5151 // Returns Instance::null() if instance cannot be canonicalized. | 5154 // Returns Instance::null() if instance cannot be canonicalized. |
5152 // Any non-canonical number of string will be canonicalized here. | 5155 // Any non-canonical number of string will be canonicalized here. |
5153 // An instance cannot be canonicalized if it still contains non-canonical | 5156 // An instance cannot be canonicalized if it still contains non-canonical |
5154 // instances in its fields. | 5157 // instances in its fields. |
5155 // Returns error in error_str, pass NULL if an error cannot occur. | 5158 // Returns error in error_str, pass NULL if an error cannot occur. |
5156 virtual RawInstance* CheckAndCanonicalize(const char** error_str) const; | 5159 virtual RawInstance* CheckAndCanonicalize(const char** error_str) const; |
5157 | 5160 |
5158 // Returns true if all fields are OK for canonicalization. | 5161 // Returns true if all fields are OK for canonicalization. |
5159 virtual bool CheckAndCanonicalizeFields(const char** error_str) const; | 5162 virtual bool CheckAndCanonicalizeFields(Zone* zone, |
| 5163 const char** error_str) const; |
5160 | 5164 |
5161 RawObject* GetField(const Field& field) const { | 5165 RawObject* GetField(const Field& field) const { |
5162 return *FieldAddr(field); | 5166 return *FieldAddr(field); |
5163 } | 5167 } |
5164 | 5168 |
5165 void SetField(const Field& field, const Object& value) const { | 5169 void SetField(const Field& field, const Object& value) const { |
5166 field.RecordStore(value); | 5170 field.RecordStore(value); |
5167 StorePointer(FieldAddr(field), value.raw()); | 5171 StorePointer(FieldAddr(field), value.raw()); |
5168 } | 5172 } |
5169 | 5173 |
(...skipping 766 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5936 FINAL_HEAP_OBJECT_IMPLEMENTATION(MixinAppType, AbstractType); | 5940 FINAL_HEAP_OBJECT_IMPLEMENTATION(MixinAppType, AbstractType); |
5937 friend class Class; | 5941 friend class Class; |
5938 }; | 5942 }; |
5939 | 5943 |
5940 | 5944 |
5941 class Number : public Instance { | 5945 class Number : public Instance { |
5942 public: | 5946 public: |
5943 // TODO(iposva): Add more useful Number methods. | 5947 // TODO(iposva): Add more useful Number methods. |
5944 RawString* ToString(Heap::Space space) const; | 5948 RawString* ToString(Heap::Space space) const; |
5945 | 5949 |
| 5950 // Numbers are canonicalized differently from other instances/strings. |
| 5951 virtual RawInstance* CheckAndCanonicalize(const char** error_str) const; |
| 5952 |
5946 private: | 5953 private: |
5947 OBJECT_IMPLEMENTATION(Number, Instance); | 5954 OBJECT_IMPLEMENTATION(Number, Instance); |
5948 | 5955 |
5949 friend class Class; | 5956 friend class Class; |
5950 }; | 5957 }; |
5951 | 5958 |
5952 | 5959 |
5953 class Integer : public Number { | 5960 class Integer : public Number { |
5954 public: | 5961 public: |
5955 static RawInteger* New(const String& str, Heap::Space space = Heap::kNew); | 5962 static RawInteger* New(const String& str, Heap::Space space = Heap::kNew); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6009 static const intptr_t kMaxValue = kSmiMax; | 6016 static const intptr_t kMaxValue = kSmiMax; |
6010 static const intptr_t kMinValue = kSmiMin; | 6017 static const intptr_t kMinValue = kSmiMin; |
6011 | 6018 |
6012 intptr_t Value() const { | 6019 intptr_t Value() const { |
6013 return ValueFromRaw(raw_value()); | 6020 return ValueFromRaw(raw_value()); |
6014 } | 6021 } |
6015 | 6022 |
6016 virtual bool Equals(const Instance& other) const; | 6023 virtual bool Equals(const Instance& other) const; |
6017 virtual bool IsZero() const { return Value() == 0; } | 6024 virtual bool IsZero() const { return Value() == 0; } |
6018 virtual bool IsNegative() const { return Value() < 0; } | 6025 virtual bool IsNegative() const { return Value() < 0; } |
6019 // Smi values are implicitly canonicalized. | |
6020 virtual RawInstance* CheckAndCanonicalize(const char** error_str) const { | |
6021 return reinterpret_cast<RawSmi*>(raw_value()); | |
6022 } | |
6023 | 6026 |
6024 virtual double AsDoubleValue() const; | 6027 virtual double AsDoubleValue() const; |
6025 virtual int64_t AsInt64Value() const; | 6028 virtual int64_t AsInt64Value() const; |
6026 virtual uint32_t AsTruncatedUint32Value() const; | 6029 virtual uint32_t AsTruncatedUint32Value() const; |
6027 | 6030 |
6028 virtual bool FitsIntoSmi() const { return true; } | 6031 virtual bool FitsIntoSmi() const { return true; } |
6029 | 6032 |
6030 virtual int CompareWith(const Integer& other) const; | 6033 virtual int CompareWith(const Integer& other) const; |
6031 | 6034 |
6032 static intptr_t InstanceSize() { return 0; } | 6035 static intptr_t InstanceSize() { return 0; } |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6132 | 6135 |
6133 static RawMint* New(int64_t value, Heap::Space space = Heap::kNew); | 6136 static RawMint* New(int64_t value, Heap::Space space = Heap::kNew); |
6134 | 6137 |
6135 static RawMint* NewCanonical(int64_t value); | 6138 static RawMint* NewCanonical(int64_t value); |
6136 | 6139 |
6137 private: | 6140 private: |
6138 void set_value(int64_t value) const; | 6141 void set_value(int64_t value) const; |
6139 | 6142 |
6140 MINT_OBJECT_IMPLEMENTATION(Mint, Integer, Integer); | 6143 MINT_OBJECT_IMPLEMENTATION(Mint, Integer, Integer); |
6141 friend class Class; | 6144 friend class Class; |
| 6145 friend class Number; |
6142 }; | 6146 }; |
6143 | 6147 |
6144 | 6148 |
6145 class Bigint : public Integer { | 6149 class Bigint : public Integer { |
6146 public: | 6150 public: |
6147 virtual bool IsZero() const { return Used() == 0;} | 6151 virtual bool IsZero() const { return Used() == 0;} |
6148 virtual bool IsNegative() const { return Neg(); } | 6152 virtual bool IsNegative() const { return Neg(); } |
6149 virtual bool Equals(const Instance& other) const; | 6153 virtual bool Equals(const Instance& other) const; |
6150 | 6154 |
6151 virtual double AsDoubleValue() const; | 6155 virtual double AsDoubleValue() const; |
6152 virtual int64_t AsInt64Value() const; | 6156 virtual int64_t AsInt64Value() const; |
6153 virtual int64_t AsTruncatedInt64Value() const; | 6157 virtual int64_t AsTruncatedInt64Value() const; |
6154 virtual uint32_t AsTruncatedUint32Value() const; | 6158 virtual uint32_t AsTruncatedUint32Value() const; |
6155 | 6159 |
6156 virtual int CompareWith(const Integer& other) const; | 6160 virtual int CompareWith(const Integer& other) const; |
6157 | 6161 |
6158 virtual bool CheckAndCanonicalizeFields(const char** error_str) const; | 6162 virtual bool CheckAndCanonicalizeFields(Zone* zone, |
| 6163 const char** error_str) const; |
6159 | 6164 |
6160 virtual bool FitsIntoSmi() const; | 6165 virtual bool FitsIntoSmi() const; |
6161 bool FitsIntoInt64() const; | 6166 bool FitsIntoInt64() const; |
6162 bool FitsIntoUint64() const; | 6167 bool FitsIntoUint64() const; |
6163 uint64_t AsUint64Value() const; | 6168 uint64_t AsUint64Value() const; |
6164 | 6169 |
6165 static intptr_t InstanceSize() { | 6170 static intptr_t InstanceSize() { |
6166 return RoundedAllocationSize(sizeof(RawBigint)); | 6171 return RoundedAllocationSize(sizeof(RawBigint)); |
6167 } | 6172 } |
6168 | 6173 |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6263 return RoundedAllocationSize(sizeof(RawDouble)); | 6268 return RoundedAllocationSize(sizeof(RawDouble)); |
6264 } | 6269 } |
6265 | 6270 |
6266 static intptr_t value_offset() { return OFFSET_OF(RawDouble, value_); } | 6271 static intptr_t value_offset() { return OFFSET_OF(RawDouble, value_); } |
6267 | 6272 |
6268 private: | 6273 private: |
6269 void set_value(double value) const; | 6274 void set_value(double value) const; |
6270 | 6275 |
6271 FINAL_HEAP_OBJECT_IMPLEMENTATION(Double, Number); | 6276 FINAL_HEAP_OBJECT_IMPLEMENTATION(Double, Number); |
6272 friend class Class; | 6277 friend class Class; |
| 6278 friend class Number; |
6273 }; | 6279 }; |
6274 | 6280 |
6275 | 6281 |
6276 // String may not be '\0' terminated. | 6282 // String may not be '\0' terminated. |
6277 class String : public Instance { | 6283 class String : public Instance { |
6278 public: | 6284 public: |
6279 // We use 30 bits for the hash code so that we consistently use a | 6285 // We use 30 bits for the hash code so that we consistently use a |
6280 // 32bit Smi representation for the hash code on all architectures. | 6286 // 32bit Smi representation for the hash code on all architectures. |
6281 static const intptr_t kHashBits = 30; | 6287 static const intptr_t kHashBits = 30; |
6282 | 6288 |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6394 } | 6400 } |
6395 virtual bool CanonicalizeEquals(const Instance& other) const { | 6401 virtual bool CanonicalizeEquals(const Instance& other) const { |
6396 return Equals(other); | 6402 return Equals(other); |
6397 } | 6403 } |
6398 virtual bool Equals(const Instance& other) const; | 6404 virtual bool Equals(const Instance& other) const; |
6399 | 6405 |
6400 intptr_t CompareTo(const String& other) const; | 6406 intptr_t CompareTo(const String& other) const; |
6401 | 6407 |
6402 bool StartsWith(const String& other) const; | 6408 bool StartsWith(const String& other) const; |
6403 | 6409 |
| 6410 // Strings are canonicalized using the symbol table. |
6404 virtual RawInstance* CheckAndCanonicalize(const char** error_str) const; | 6411 virtual RawInstance* CheckAndCanonicalize(const char** error_str) const; |
6405 | 6412 |
6406 bool IsSymbol() const { return raw()->IsCanonical(); } | 6413 bool IsSymbol() const { return raw()->IsCanonical(); } |
6407 | 6414 |
6408 bool IsOneByteString() const { | 6415 bool IsOneByteString() const { |
6409 return raw()->GetClassId() == kOneByteStringCid; | 6416 return raw()->GetClassId() == kOneByteStringCid; |
6410 } | 6417 } |
6411 | 6418 |
6412 bool IsTwoByteString() const { | 6419 bool IsTwoByteString() const { |
6413 return raw()->GetClassId() == kTwoByteStringCid; | 6420 return raw()->GetClassId() == kTwoByteStringCid; |
(...skipping 683 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7097 } | 7104 } |
7098 | 7105 |
7099 static intptr_t InstanceSize(intptr_t len) { | 7106 static intptr_t InstanceSize(intptr_t len) { |
7100 // Ensure that variable length data is not adding to the object length. | 7107 // Ensure that variable length data is not adding to the object length. |
7101 ASSERT(sizeof(RawArray) == (sizeof(RawInstance) + (2 * kWordSize))); | 7108 ASSERT(sizeof(RawArray) == (sizeof(RawInstance) + (2 * kWordSize))); |
7102 ASSERT(0 <= len && len <= kMaxElements); | 7109 ASSERT(0 <= len && len <= kMaxElements); |
7103 return RoundedAllocationSize(sizeof(RawArray) + (len * kBytesPerElement)); | 7110 return RoundedAllocationSize(sizeof(RawArray) + (len * kBytesPerElement)); |
7104 } | 7111 } |
7105 | 7112 |
7106 // Returns true if all elements are OK for canonicalization. | 7113 // Returns true if all elements are OK for canonicalization. |
7107 virtual bool CheckAndCanonicalizeFields(const char** error_str) const; | 7114 virtual bool CheckAndCanonicalizeFields(Zone* zone, |
| 7115 const char** error_str) const; |
7108 | 7116 |
7109 // Make the array immutable to Dart code by switching the class pointer | 7117 // Make the array immutable to Dart code by switching the class pointer |
7110 // to ImmutableArray. | 7118 // to ImmutableArray. |
7111 void MakeImmutable() const; | 7119 void MakeImmutable() const; |
7112 | 7120 |
7113 static RawArray* New(intptr_t len, Heap::Space space = Heap::kNew); | 7121 static RawArray* New(intptr_t len, Heap::Space space = Heap::kNew); |
7114 | 7122 |
7115 // Creates and returns a new array with 'new_length'. Copies all elements from | 7123 // Creates and returns a new array with 'new_length'. Copies all elements from |
7116 // 'source' to the new array. 'new_length' must be greater than or equal to | 7124 // 'source' to the new array. 'new_length' must be greater than or equal to |
7117 // 'source.Length()'. 'source' can be null. | 7125 // 'source.Length()'. 'source' can be null. |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7243 // reusing the type argument vector of the instantiator. | 7251 // reusing the type argument vector of the instantiator. |
7244 ASSERT(value.IsNull() || | 7252 ASSERT(value.IsNull() || |
7245 ((value.Length() >= 1) && | 7253 ((value.Length() >= 1) && |
7246 value.IsInstantiated() && | 7254 value.IsInstantiated() && |
7247 value.IsCanonical())); | 7255 value.IsCanonical())); |
7248 const Array& contents = Array::Handle(data()); | 7256 const Array& contents = Array::Handle(data()); |
7249 contents.SetTypeArguments(value); | 7257 contents.SetTypeArguments(value); |
7250 StorePointer(&raw_ptr()->type_arguments_, value.raw()); | 7258 StorePointer(&raw_ptr()->type_arguments_, value.raw()); |
7251 } | 7259 } |
7252 | 7260 |
7253 virtual bool CanonicalizeEquals(const Instance& other) const; | 7261 // We don't expect a growable object array to be canonicalized. |
| 7262 virtual bool CanonicalizeEquals(const Instance& other) const { |
| 7263 UNREACHABLE(); |
| 7264 return false; |
| 7265 } |
7254 | 7266 |
| 7267 // We don't expect a growable object array to be canonicalized. |
7255 virtual RawInstance* CheckAndCanonicalize(const char** error_str) const { | 7268 virtual RawInstance* CheckAndCanonicalize(const char** error_str) const { |
7256 UNREACHABLE(); | 7269 UNREACHABLE(); |
7257 return Instance::null(); | 7270 return Instance::null(); |
7258 } | 7271 } |
7259 | 7272 |
7260 static intptr_t type_arguments_offset() { | 7273 static intptr_t type_arguments_offset() { |
7261 return OFFSET_OF(RawGrowableObjectArray, type_arguments_); | 7274 return OFFSET_OF(RawGrowableObjectArray, type_arguments_); |
7262 } | 7275 } |
7263 | 7276 |
7264 static intptr_t length_offset() { | 7277 static intptr_t length_offset() { |
(...skipping 669 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7934 | 7947 |
7935 static intptr_t type_arguments_offset() { | 7948 static intptr_t type_arguments_offset() { |
7936 return OFFSET_OF(RawClosure, type_arguments_); | 7949 return OFFSET_OF(RawClosure, type_arguments_); |
7937 } | 7950 } |
7938 | 7951 |
7939 static intptr_t InstanceSize() { | 7952 static intptr_t InstanceSize() { |
7940 return RoundedAllocationSize(sizeof(RawClosure)); | 7953 return RoundedAllocationSize(sizeof(RawClosure)); |
7941 } | 7954 } |
7942 | 7955 |
7943 // Returns true if all elements are OK for canonicalization. | 7956 // Returns true if all elements are OK for canonicalization. |
7944 virtual bool CheckAndCanonicalizeFields(const char** error_str) const { | 7957 virtual bool CheckAndCanonicalizeFields(Zone* zone, |
| 7958 const char** error_str) const { |
7945 // None of the fields of a closure are instances. | 7959 // None of the fields of a closure are instances. |
7946 return true; | 7960 return true; |
7947 } | 7961 } |
7948 | 7962 |
7949 static RawClosure* New(const Function& function, | 7963 static RawClosure* New(const Function& function, |
7950 const Context& context, | 7964 const Context& context, |
7951 Heap::Space space = Heap::kNew); | 7965 Heap::Space space = Heap::kNew); |
7952 | 7966 |
7953 private: | 7967 private: |
7954 static RawClosure* New(); | 7968 static RawClosure* New(); |
(...skipping 483 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8438 | 8452 |
8439 | 8453 |
8440 RawObject* MegamorphicCache::GetTargetFunction(const Array& array, | 8454 RawObject* MegamorphicCache::GetTargetFunction(const Array& array, |
8441 intptr_t index) { | 8455 intptr_t index) { |
8442 return array.At((index * kEntryLength) + kTargetFunctionIndex); | 8456 return array.At((index * kEntryLength) + kTargetFunctionIndex); |
8443 } | 8457 } |
8444 | 8458 |
8445 } // namespace dart | 8459 } // namespace dart |
8446 | 8460 |
8447 #endif // VM_OBJECT_H_ | 8461 #endif // VM_OBJECT_H_ |
OLD | NEW |