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