| 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" |
| 11 #include "vm/json_stream.h" | 11 #include "vm/json_stream.h" |
| 12 #include "vm/bitmap.h" | 12 #include "vm/bitmap.h" |
| 13 #include "vm/dart.h" | 13 #include "vm/dart.h" |
| 14 #include "vm/flags.h" |
| 14 #include "vm/globals.h" | 15 #include "vm/globals.h" |
| 15 #include "vm/growable_array.h" | 16 #include "vm/growable_array.h" |
| 16 #include "vm/handles.h" | 17 #include "vm/handles.h" |
| 17 #include "vm/heap.h" | 18 #include "vm/heap.h" |
| 18 #include "vm/isolate.h" | 19 #include "vm/isolate.h" |
| 19 #include "vm/method_recognizer.h" | 20 #include "vm/method_recognizer.h" |
| 20 #include "vm/os.h" | 21 #include "vm/os.h" |
| 21 #include "vm/raw_object.h" | 22 #include "vm/raw_object.h" |
| 22 #include "vm/report.h" | 23 #include "vm/report.h" |
| 23 #include "vm/scanner.h" | 24 #include "vm/scanner.h" |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 130 return reinterpret_cast<const object&>(obj); \ | 131 return reinterpret_cast<const object&>(obj); \ |
| 131 } \ | 132 } \ |
| 132 static Raw##object* RawCast(RawObject* raw) { \ | 133 static Raw##object* RawCast(RawObject* raw) { \ |
| 133 ASSERT(Object::Handle(raw).Is##object()); \ | 134 ASSERT(Object::Handle(raw).Is##object()); \ |
| 134 return reinterpret_cast<Raw##object*>(raw); \ | 135 return reinterpret_cast<Raw##object*>(raw); \ |
| 135 } \ | 136 } \ |
| 136 static Raw##object* null() { \ | 137 static Raw##object* null() { \ |
| 137 return reinterpret_cast<Raw##object*>(Object::null()); \ | 138 return reinterpret_cast<Raw##object*>(Object::null()); \ |
| 138 } \ | 139 } \ |
| 139 virtual const char* ToCString() const; \ | 140 virtual const char* ToCString() const; \ |
| 140 /* Object is printed as JSON into stream. If ref is true only a header */ \ | |
| 141 /* with an object id is printed. If ref is false the object is fully */ \ | |
| 142 /* printed. */ \ | |
| 143 virtual const char* JSONType() const { \ | |
| 144 return ""#object; \ | |
| 145 } \ | |
| 146 static const ClassId kClassId = k##object##Cid; \ | 141 static const ClassId kClassId = k##object##Cid; \ |
| 147 protected: /* NOLINT */ \ | |
| 148 virtual void PrintJSONImpl(JSONStream* stream, bool ref) const; \ | |
| 149 private: /* NOLINT */ \ | 142 private: /* NOLINT */ \ |
| 150 /* Initialize the handle based on the raw_ptr in the presence of null. */ \ | 143 /* Initialize the handle based on the raw_ptr in the presence of null. */ \ |
| 151 static void initializeHandle(object* obj, RawObject* raw_ptr) { \ | 144 static void initializeHandle(object* obj, RawObject* raw_ptr) { \ |
| 152 if (raw_ptr != Object::null()) { \ | 145 if (raw_ptr != Object::null()) { \ |
| 153 obj->SetRaw(raw_ptr); \ | 146 obj->SetRaw(raw_ptr); \ |
| 154 } else { \ | 147 } else { \ |
| 155 obj->raw_ = Object::null(); \ | 148 obj->raw_ = Object::null(); \ |
| 156 object fake_object; \ | 149 object fake_object; \ |
| 157 obj->set_vtable(fake_object.vtable()); \ | 150 obj->set_vtable(fake_object.vtable()); \ |
| 158 } \ | 151 } \ |
| 159 } \ | 152 } \ |
| 160 /* Disallow allocation, copy constructors and override super assignment. */ \ | 153 /* Disallow allocation, copy constructors and override super assignment. */ \ |
| 161 public: /* NOLINT */ \ | 154 public: /* NOLINT */ \ |
| 162 void operator delete(void* pointer) { \ | 155 void operator delete(void* pointer) { \ |
| 163 UNREACHABLE(); \ | 156 UNREACHABLE(); \ |
| 164 } \ | 157 } \ |
| 165 private: /* NOLINT */ \ | 158 private: /* NOLINT */ \ |
| 166 void* operator new(size_t size); \ | 159 void* operator new(size_t size); \ |
| 167 object(const object& value); \ | 160 object(const object& value); \ |
| 168 void operator=(Raw##super* value); \ | 161 void operator=(Raw##super* value); \ |
| 169 void operator=(const object& value); \ | 162 void operator=(const object& value); \ |
| 170 void operator=(const super& value); \ | 163 void operator=(const super& value); \ |
| 171 | 164 |
| 165 // Conditionally include object_service.cc functionality in the vtable to avoid |
| 166 // link errors like the following: |
| 167 // |
| 168 // object.o:(.rodata._ZTVN4....E[_ZTVN4...E]+0x278): |
| 169 // undefined reference to |
| 170 // `dart::Instance::PrintSharedInstanceJSON(dart::JSONObject*, bool) const'. |
| 171 // |
| 172 #ifndef PRODUCT |
| 173 #define OBJECT_SERVICE_SUPPORT(object) \ |
| 174 protected: /* NOLINT */ \ |
| 175 /* Object is printed as JSON into stream. If ref is true only a header */ \ |
| 176 /* with an object id is printed. If ref is false the object is fully */ \ |
| 177 /* printed. */ \ |
| 178 virtual void PrintJSONImpl(JSONStream* stream, bool ref) const; \ |
| 179 virtual const char* JSONType() const { \ |
| 180 return ""#object; \ |
| 181 } |
| 182 #else |
| 183 #define OBJECT_SERVICE_SUPPORT(object) \ |
| 184 protected: /* NOLINT */ |
| 185 #endif // !PRODUCT |
| 186 |
| 172 #define SNAPSHOT_READER_SUPPORT(object) \ | 187 #define SNAPSHOT_READER_SUPPORT(object) \ |
| 173 static Raw##object* ReadFrom(SnapshotReader* reader, \ | 188 static Raw##object* ReadFrom(SnapshotReader* reader, \ |
| 174 intptr_t object_id, \ | 189 intptr_t object_id, \ |
| 175 intptr_t tags, \ | 190 intptr_t tags, \ |
| 176 Snapshot::Kind, \ | 191 Snapshot::Kind, \ |
| 177 bool as_reference); \ | 192 bool as_reference); \ |
| 178 friend class SnapshotReader; \ | 193 friend class SnapshotReader; \ |
| 179 | 194 |
| 180 #define OBJECT_IMPLEMENTATION(object, super) \ | 195 #define OBJECT_IMPLEMENTATION(object, super) \ |
| 181 public: /* NOLINT */ \ | 196 public: /* NOLINT */ \ |
| 182 void operator=(Raw##object* value) { \ | 197 void operator=(Raw##object* value) { \ |
| 183 initializeHandle(this, value); \ | 198 initializeHandle(this, value); \ |
| 184 } \ | 199 } \ |
| 185 void operator^=(RawObject* value) { \ | 200 void operator^=(RawObject* value) { \ |
| 186 initializeHandle(this, value); \ | 201 initializeHandle(this, value); \ |
| 187 ASSERT(IsNull() || Is##object()); \ | 202 ASSERT(IsNull() || Is##object()); \ |
| 188 } \ | 203 } \ |
| 189 protected: /* NOLINT */ \ | 204 protected: /* NOLINT */ \ |
| 190 object() : super() {} \ | 205 object() : super() {} \ |
| 191 BASE_OBJECT_IMPLEMENTATION(object, super) \ | 206 BASE_OBJECT_IMPLEMENTATION(object, super) \ |
| 207 OBJECT_SERVICE_SUPPORT(object) |
| 192 | 208 |
| 193 #define HEAP_OBJECT_IMPLEMENTATION(object, super) \ | 209 #define HEAP_OBJECT_IMPLEMENTATION(object, super) \ |
| 194 OBJECT_IMPLEMENTATION(object, super); \ | 210 OBJECT_IMPLEMENTATION(object, super); \ |
| 195 const Raw##object* raw_ptr() const { \ | 211 const Raw##object* raw_ptr() const { \ |
| 196 ASSERT(raw() != null()); \ | 212 ASSERT(raw() != null()); \ |
| 197 return raw()->ptr(); \ | 213 return raw()->ptr(); \ |
| 198 } \ | 214 } \ |
| 199 SNAPSHOT_READER_SUPPORT(object) \ | 215 SNAPSHOT_READER_SUPPORT(object) \ |
| 200 friend class StackFrame; \ | 216 friend class StackFrame; \ |
| 201 friend class Thread; \ | 217 friend class Thread; \ |
| 202 | 218 |
| 203 // This macro is used to denote types that do not have a sub-type. | 219 // This macro is used to denote types that do not have a sub-type. |
| 204 #define FINAL_HEAP_OBJECT_IMPLEMENTATION_HELPER(object, rettype, super) \ | 220 #define FINAL_HEAP_OBJECT_IMPLEMENTATION_HELPER(object, rettype, super) \ |
| 205 public: /* NOLINT */ \ | 221 public: /* NOLINT */ \ |
| 206 void operator=(Raw##object* value) { \ | 222 void operator=(Raw##object* value) { \ |
| 207 raw_ = value; \ | 223 raw_ = value; \ |
| 208 CHECK_HANDLE(); \ | 224 CHECK_HANDLE(); \ |
| 209 } \ | 225 } \ |
| 210 void operator^=(RawObject* value) { \ | 226 void operator^=(RawObject* value) { \ |
| 211 raw_ = value; \ | 227 raw_ = value; \ |
| 212 CHECK_HANDLE(); \ | 228 CHECK_HANDLE(); \ |
| 213 } \ | 229 } \ |
| 214 private: /* NOLINT */ \ | 230 private: /* NOLINT */ \ |
| 215 object() : super() {} \ | 231 object() : super() {} \ |
| 216 BASE_OBJECT_IMPLEMENTATION(object, super) \ | 232 BASE_OBJECT_IMPLEMENTATION(object, super) \ |
| 233 OBJECT_SERVICE_SUPPORT(object) \ |
| 217 const Raw##object* raw_ptr() const { \ | 234 const Raw##object* raw_ptr() const { \ |
| 218 ASSERT(raw() != null()); \ | 235 ASSERT(raw() != null()); \ |
| 219 return raw()->ptr(); \ | 236 return raw()->ptr(); \ |
| 220 } \ | 237 } \ |
| 221 static intptr_t NextFieldOffset() { \ | 238 static intptr_t NextFieldOffset() { \ |
| 222 return -kWordSize; \ | 239 return -kWordSize; \ |
| 223 } \ | 240 } \ |
| 224 SNAPSHOT_READER_SUPPORT(rettype) \ | 241 SNAPSHOT_READER_SUPPORT(rettype) \ |
| 225 friend class StackFrame; \ | 242 friend class StackFrame; \ |
| 226 friend class Thread; \ | 243 friend class Thread; \ |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 273 | 290 |
| 274 // Matches Object.toString on instances (except String::ToCString, bug 20583). | 291 // Matches Object.toString on instances (except String::ToCString, bug 20583). |
| 275 virtual const char* ToCString() const { | 292 virtual const char* ToCString() const { |
| 276 if (IsNull()) { | 293 if (IsNull()) { |
| 277 return "null"; | 294 return "null"; |
| 278 } else { | 295 } else { |
| 279 return "Object"; | 296 return "Object"; |
| 280 } | 297 } |
| 281 } | 298 } |
| 282 | 299 |
| 300 #ifndef PRODUCT |
| 283 void PrintJSON(JSONStream* stream, bool ref = true) const; | 301 void PrintJSON(JSONStream* stream, bool ref = true) const; |
| 284 | 302 virtual void PrintJSONImpl(JSONStream* stream, bool ref) const; |
| 285 virtual const char* JSONType() const { | 303 virtual const char* JSONType() const { |
| 286 return IsNull() ? "null" : "Object"; | 304 return IsNull() ? "null" : "Object"; |
| 287 } | 305 } |
| 306 #endif |
| 288 | 307 |
| 289 // Returns the name that is used to identify an object in the | 308 // Returns the name that is used to identify an object in the |
| 290 // namespace dictionary. | 309 // namespace dictionary. |
| 291 // Object::DictionaryName() returns String::null(). Only subclasses | 310 // Object::DictionaryName() returns String::null(). Only subclasses |
| 292 // of Object that need to be entered in the library and library prefix | 311 // of Object that need to be entered in the library and library prefix |
| 293 // namespaces need to provide an implementation. | 312 // namespaces need to provide an implementation. |
| 294 virtual RawString* DictionaryName() const; | 313 virtual RawString* DictionaryName() const; |
| 295 | 314 |
| 296 bool IsNew() const { return raw()->IsNewObject(); } | 315 bool IsNew() const { return raw()->IsNewObject(); } |
| 297 bool IsOld() const { return raw()->IsOldObject(); } | 316 bool IsOld() const { return raw()->IsOldObject(); } |
| (...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 701 | 720 |
| 702 // End of field mutator guards. | 721 // End of field mutator guards. |
| 703 | 722 |
| 704 RawObject* raw_; // The raw object reference. | 723 RawObject* raw_; // The raw object reference. |
| 705 | 724 |
| 706 protected: | 725 protected: |
| 707 void AddCommonObjectProperties(JSONObject* jsobj, | 726 void AddCommonObjectProperties(JSONObject* jsobj, |
| 708 const char* protocol_type, | 727 const char* protocol_type, |
| 709 bool ref) const; | 728 bool ref) const; |
| 710 | 729 |
| 711 virtual void PrintJSONImpl(JSONStream* stream, bool ref) const; | |
| 712 | |
| 713 private: | 730 private: |
| 714 static intptr_t NextFieldOffset() { | 731 static intptr_t NextFieldOffset() { |
| 715 // Indicates this class cannot be extended by dart code. | 732 // Indicates this class cannot be extended by dart code. |
| 716 return -kWordSize; | 733 return -kWordSize; |
| 717 } | 734 } |
| 718 | 735 |
| 719 static void InitializeObject(uword address, | 736 static void InitializeObject(uword address, |
| 720 intptr_t id, | 737 intptr_t id, |
| 721 intptr_t size, | 738 intptr_t size, |
| 722 bool is_vm_object); | 739 bool is_vm_object); |
| (...skipping 4378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5101 return RoundedAllocationSize(sizeof(RawInstance)); | 5118 return RoundedAllocationSize(sizeof(RawInstance)); |
| 5102 } | 5119 } |
| 5103 | 5120 |
| 5104 static RawInstance* New(const Class& cls, Heap::Space space = Heap::kNew); | 5121 static RawInstance* New(const Class& cls, Heap::Space space = Heap::kNew); |
| 5105 | 5122 |
| 5106 // Array/list element address computations. | 5123 // Array/list element address computations. |
| 5107 static intptr_t DataOffsetFor(intptr_t cid); | 5124 static intptr_t DataOffsetFor(intptr_t cid); |
| 5108 static intptr_t ElementSizeFor(intptr_t cid); | 5125 static intptr_t ElementSizeFor(intptr_t cid); |
| 5109 | 5126 |
| 5110 protected: | 5127 protected: |
| 5128 #ifndef PRODUCT |
| 5111 virtual void PrintSharedInstanceJSON(JSONObject* jsobj, bool ref) const; | 5129 virtual void PrintSharedInstanceJSON(JSONObject* jsobj, bool ref) const; |
| 5130 #endif |
| 5112 | 5131 |
| 5113 private: | 5132 private: |
| 5114 RawObject** FieldAddrAtOffset(intptr_t offset) const { | 5133 RawObject** FieldAddrAtOffset(intptr_t offset) const { |
| 5115 ASSERT(IsValidFieldOffset(offset)); | 5134 ASSERT(IsValidFieldOffset(offset)); |
| 5116 return reinterpret_cast<RawObject**>(raw_value() - kHeapObjectTag + offset); | 5135 return reinterpret_cast<RawObject**>(raw_value() - kHeapObjectTag + offset); |
| 5117 } | 5136 } |
| 5118 RawObject** FieldAddr(const Field& field) const { | 5137 RawObject** FieldAddr(const Field& field) const { |
| 5119 return FieldAddrAtOffset(field.Offset()); | 5138 return FieldAddrAtOffset(field.Offset()); |
| 5120 } | 5139 } |
| 5121 RawObject** NativeFieldsAddr() const { | 5140 RawObject** NativeFieldsAddr() const { |
| (...skipping 766 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5888 }; | 5907 }; |
| 5889 | 5908 |
| 5890 | 5909 |
| 5891 class Number : public Instance { | 5910 class Number : public Instance { |
| 5892 public: | 5911 public: |
| 5893 // TODO(iposva): Add more useful Number methods. | 5912 // TODO(iposva): Add more useful Number methods. |
| 5894 RawString* ToString(Heap::Space space) const; | 5913 RawString* ToString(Heap::Space space) const; |
| 5895 | 5914 |
| 5896 private: | 5915 private: |
| 5897 OBJECT_IMPLEMENTATION(Number, Instance); | 5916 OBJECT_IMPLEMENTATION(Number, Instance); |
| 5917 |
| 5898 friend class Class; | 5918 friend class Class; |
| 5899 }; | 5919 }; |
| 5900 | 5920 |
| 5901 | 5921 |
| 5902 class Integer : public Number { | 5922 class Integer : public Number { |
| 5903 public: | 5923 public: |
| 5904 static RawInteger* New(const String& str, Heap::Space space = Heap::kNew); | 5924 static RawInteger* New(const String& str, Heap::Space space = Heap::kNew); |
| 5905 static RawInteger* NewFromUint64(uint64_t value, | 5925 static RawInteger* NewFromUint64(uint64_t value, |
| 5906 Heap::Space space = Heap::kNew); | 5926 Heap::Space space = Heap::kNew); |
| 5907 | 5927 |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6029 static intptr_t ValueFromRaw(uword raw_value) { | 6049 static intptr_t ValueFromRaw(uword raw_value) { |
| 6030 intptr_t value = raw_value; | 6050 intptr_t value = raw_value; |
| 6031 ASSERT((value & kSmiTagMask) == kSmiTag); | 6051 ASSERT((value & kSmiTagMask) == kSmiTag); |
| 6032 return (value >> kSmiTagShift); | 6052 return (value >> kSmiTagShift); |
| 6033 } | 6053 } |
| 6034 | 6054 |
| 6035 static cpp_vtable handle_vtable_; | 6055 static cpp_vtable handle_vtable_; |
| 6036 | 6056 |
| 6037 Smi() : Integer() {} | 6057 Smi() : Integer() {} |
| 6038 BASE_OBJECT_IMPLEMENTATION(Smi, Integer); | 6058 BASE_OBJECT_IMPLEMENTATION(Smi, Integer); |
| 6039 | 6059 OBJECT_SERVICE_SUPPORT(Smi); |
| 6040 friend class Api; // For ValueFromRaw | 6060 friend class Api; // For ValueFromRaw |
| 6041 friend class Class; | 6061 friend class Class; |
| 6042 friend class Object; | 6062 friend class Object; |
| 6043 }; | 6063 }; |
| 6044 | 6064 |
| 6045 | 6065 |
| 6046 class Mint : public Integer { | 6066 class Mint : public Integer { |
| 6047 public: | 6067 public: |
| 6048 static const intptr_t kBits = 63; // 64-th bit is sign. | 6068 static const intptr_t kBits = 63; // 64-th bit is sign. |
| 6049 static const int64_t kMaxValue = | 6069 static const int64_t kMaxValue = |
| (...skipping 2349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8399 | 8419 |
| 8400 | 8420 |
| 8401 RawObject* MegamorphicCache::GetTargetFunction(const Array& array, | 8421 RawObject* MegamorphicCache::GetTargetFunction(const Array& array, |
| 8402 intptr_t index) { | 8422 intptr_t index) { |
| 8403 return array.At((index * kEntryLength) + kTargetFunctionIndex); | 8423 return array.At((index * kEntryLength) + kTargetFunctionIndex); |
| 8404 } | 8424 } |
| 8405 | 8425 |
| 8406 } // namespace dart | 8426 } // namespace dart |
| 8407 | 8427 |
| 8408 #endif // VM_OBJECT_H_ | 8428 #endif // VM_OBJECT_H_ |
| OLD | NEW |