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 13 matching lines...) Expand all Loading... |
24 // Forward declarations. | 24 // Forward declarations. |
25 #define DEFINE_FORWARD_DECLARATION(clazz) \ | 25 #define DEFINE_FORWARD_DECLARATION(clazz) \ |
26 class clazz; | 26 class clazz; |
27 CLASS_LIST(DEFINE_FORWARD_DECLARATION) | 27 CLASS_LIST(DEFINE_FORWARD_DECLARATION) |
28 #undef DEFINE_FORWARD_DECLARATION | 28 #undef DEFINE_FORWARD_DECLARATION |
29 class Api; | 29 class Api; |
30 class ArgumentsDescriptor; | 30 class ArgumentsDescriptor; |
31 class Assembler; | 31 class Assembler; |
32 class Closure; | 32 class Closure; |
33 class Code; | 33 class Code; |
| 34 class DisassemblyFormatter; |
34 class DeoptInstr; | 35 class DeoptInstr; |
35 class FinalizablePersistentHandle; | 36 class FinalizablePersistentHandle; |
36 class LocalScope; | 37 class LocalScope; |
37 class ReusableHandleScope; | 38 class ReusableHandleScope; |
38 class ReusableObjectHandleScope; | 39 class ReusableObjectHandleScope; |
39 class Symbols; | 40 class Symbols; |
40 | 41 |
41 #if defined(DEBUG) | 42 #if defined(DEBUG) |
42 #define CHECK_HANDLE() CheckHandle(); | 43 #define CHECK_HANDLE() CheckHandle(); |
43 #else | 44 #else |
(...skipping 827 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
871 other, | 872 other, |
872 other_type_arguments, | 873 other_type_arguments, |
873 bound_error); | 874 bound_error); |
874 } | 875 } |
875 | 876 |
876 // Check if this is the top level class. | 877 // Check if this is the top level class. |
877 bool IsTopLevel() const; | 878 bool IsTopLevel() const; |
878 | 879 |
879 RawArray* fields() const { return raw_ptr()->fields_; } | 880 RawArray* fields() const { return raw_ptr()->fields_; } |
880 void SetFields(const Array& value) const; | 881 void SetFields(const Array& value) const; |
| 882 intptr_t FindFieldIndex(const Field& field) const; |
| 883 RawField* FieldFromIndex(intptr_t idx) const; |
881 | 884 |
882 // Returns an array of all fields of this class and its superclasses indexed | 885 // Returns an array of all fields of this class and its superclasses indexed |
883 // by offset in words. | 886 // by offset in words. |
884 RawArray* OffsetToFieldMap() const; | 887 RawArray* OffsetToFieldMap() const; |
885 | 888 |
886 // Returns true if non-static fields are defined. | 889 // Returns true if non-static fields are defined. |
887 bool HasInstanceFields() const; | 890 bool HasInstanceFields() const; |
888 | 891 |
889 RawArray* functions() const { return raw_ptr()->functions_; } | 892 RawArray* functions() const { return raw_ptr()->functions_; } |
890 void SetFunctions(const Array& value) const; | 893 void SetFunctions(const Array& value) const; |
891 void AddFunction(const Function& function) const; | 894 void AddFunction(const Function& function) const; |
| 895 intptr_t FindFunctionIndex(const Function& function) const; |
| 896 RawFunction* FunctionFromIndex(intptr_t idx) const; |
| 897 intptr_t FindImplicitClosureFunctionIndex(const Function& needle) const; |
| 898 RawFunction* ImplicitClosureFunctionFromIndex(intptr_t idx) const; |
892 | 899 |
893 RawGrowableObjectArray* closures() const { | 900 RawGrowableObjectArray* closures() const { |
894 return raw_ptr()->closure_functions_; | 901 return raw_ptr()->closure_functions_; |
895 } | 902 } |
896 void AddClosureFunction(const Function& function) const; | 903 void AddClosureFunction(const Function& function) const; |
897 RawFunction* LookupClosureFunction(intptr_t token_pos) const; | 904 RawFunction* LookupClosureFunction(intptr_t token_pos) const; |
| 905 intptr_t FindClosureIndex(const Function& function) const; |
| 906 RawFunction* ClosureFunctionFromIndex(intptr_t idx) const; |
898 | 907 |
899 RawFunction* LookupDynamicFunction(const String& name) const; | 908 RawFunction* LookupDynamicFunction(const String& name) const; |
900 RawFunction* LookupDynamicFunctionAllowPrivate(const String& name) const; | 909 RawFunction* LookupDynamicFunctionAllowPrivate(const String& name) const; |
901 RawFunction* LookupStaticFunction(const String& name) const; | 910 RawFunction* LookupStaticFunction(const String& name) const; |
902 RawFunction* LookupStaticFunctionAllowPrivate(const String& name) const; | 911 RawFunction* LookupStaticFunctionAllowPrivate(const String& name) const; |
903 RawFunction* LookupConstructor(const String& name) const; | 912 RawFunction* LookupConstructor(const String& name) const; |
904 RawFunction* LookupConstructorAllowPrivate(const String& name) const; | 913 RawFunction* LookupConstructorAllowPrivate(const String& name) const; |
905 RawFunction* LookupFactory(const String& name) const; | 914 RawFunction* LookupFactory(const String& name) const; |
906 RawFunction* LookupFunction(const String& name) const; | 915 RawFunction* LookupFunction(const String& name) const; |
907 RawFunction* LookupFunctionAllowPrivate(const String& name) const; | 916 RawFunction* LookupFunctionAllowPrivate(const String& name) const; |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
984 raw_ptr()->num_native_fields_ = value; | 993 raw_ptr()->num_native_fields_ = value; |
985 } | 994 } |
986 | 995 |
987 RawCode* allocation_stub() const { | 996 RawCode* allocation_stub() const { |
988 return raw_ptr()->allocation_stub_; | 997 return raw_ptr()->allocation_stub_; |
989 } | 998 } |
990 void set_allocation_stub(const Code& value) const; | 999 void set_allocation_stub(const Code& value) const; |
991 | 1000 |
992 RawArray* constants() const; | 1001 RawArray* constants() const; |
993 | 1002 |
| 1003 intptr_t FindInvocationDispatcherFunctionIndex(const Function& needle) const; |
| 1004 RawFunction* InvocationDispatcherFunctionFromIndex(intptr_t idx) const; |
| 1005 |
994 RawFunction* GetInvocationDispatcher(const String& target_name, | 1006 RawFunction* GetInvocationDispatcher(const String& target_name, |
995 const Array& args_desc, | 1007 const Array& args_desc, |
996 RawFunction::Kind kind) const; | 1008 RawFunction::Kind kind) const; |
997 | 1009 |
998 void Finalize() const; | 1010 void Finalize() const; |
999 | 1011 |
1000 // Apply given patch class to this class. | 1012 // Apply given patch class to this class. |
1001 // Return true on success, or false and error otherwise. | 1013 // Return true on success, or false and error otherwise. |
1002 bool ApplyPatch(const Class& patch, Error* error) const; | 1014 bool ApplyPatch(const Class& patch, Error* error) const; |
1003 | 1015 |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1202 virtual RawAbstractTypeArguments* InstantiateFrom( | 1214 virtual RawAbstractTypeArguments* InstantiateFrom( |
1203 const AbstractTypeArguments& instantiator_type_arguments, | 1215 const AbstractTypeArguments& instantiator_type_arguments, |
1204 Error* bound_error) const; | 1216 Error* bound_error) const; |
1205 | 1217 |
1206 // Do not clone InstantiatedTypeArguments or null vectors, since they are | 1218 // Do not clone InstantiatedTypeArguments or null vectors, since they are |
1207 // considered finalized. | 1219 // considered finalized. |
1208 virtual RawAbstractTypeArguments* CloneUnfinalized() const { | 1220 virtual RawAbstractTypeArguments* CloneUnfinalized() const { |
1209 return this->raw(); | 1221 return this->raw(); |
1210 } | 1222 } |
1211 | 1223 |
1212 // Do not canonicalize InstantiatedTypeArguments or null vectors. | 1224 // Null vectors are canonical. |
1213 virtual RawAbstractTypeArguments* Canonicalize() const { return this->raw(); } | 1225 virtual RawAbstractTypeArguments* Canonicalize() const { return this->raw(); } |
1214 | 1226 |
1215 // The name of this type argument vector, e.g. "<T, dynamic, List<T>, Smi>". | 1227 // The name of this type argument vector, e.g. "<T, dynamic, List<T>, Smi>". |
1216 virtual RawString* Name() const { | 1228 virtual RawString* Name() const { |
1217 return SubvectorName(0, Length(), kInternalName); | 1229 return SubvectorName(0, Length(), kInternalName); |
1218 } | 1230 } |
1219 | 1231 |
1220 // The name of this type argument vector, e.g. "<T, dynamic, List<T>, int>". | 1232 // The name of this type argument vector, e.g. "<T, dynamic, List<T>, int>". |
1221 // Names of internal classes are mapped to their public interfaces. | 1233 // Names of internal classes are mapped to their public interfaces. |
1222 virtual RawString* UserVisibleName() const { | 1234 virtual RawString* UserVisibleName() const { |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1376 virtual bool IsUninstantiatedIdentity() const { | 1388 virtual bool IsUninstantiatedIdentity() const { |
1377 UNREACHABLE(); | 1389 UNREACHABLE(); |
1378 return false; | 1390 return false; |
1379 } | 1391 } |
1380 virtual bool CanShareInstantiatorTypeArguments( | 1392 virtual bool CanShareInstantiatorTypeArguments( |
1381 const Class& instantiator_class) const { | 1393 const Class& instantiator_class) const { |
1382 UNREACHABLE(); | 1394 UNREACHABLE(); |
1383 return false; | 1395 return false; |
1384 } | 1396 } |
1385 virtual bool IsBounded() const { return false; } // Bounds were checked. | 1397 virtual bool IsBounded() const { return false; } // Bounds were checked. |
| 1398 virtual RawAbstractTypeArguments* Canonicalize() const; |
1386 | 1399 |
1387 RawAbstractTypeArguments* uninstantiated_type_arguments() const { | 1400 RawAbstractTypeArguments* uninstantiated_type_arguments() const { |
1388 return raw_ptr()->uninstantiated_type_arguments_; | 1401 return raw_ptr()->uninstantiated_type_arguments_; |
1389 } | 1402 } |
1390 static intptr_t uninstantiated_type_arguments_offset() { | 1403 static intptr_t uninstantiated_type_arguments_offset() { |
1391 return OFFSET_OF(RawInstantiatedTypeArguments, | 1404 return OFFSET_OF(RawInstantiatedTypeArguments, |
1392 uninstantiated_type_arguments_); | 1405 uninstantiated_type_arguments_); |
1393 } | 1406 } |
1394 | 1407 |
1395 RawAbstractTypeArguments* instantiator_type_arguments() const { | 1408 RawAbstractTypeArguments* instantiator_type_arguments() const { |
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1588 void SetRedirectionType(const Type& type) const; | 1601 void SetRedirectionType(const Type& type) const; |
1589 RawString* RedirectionIdentifier() const; | 1602 RawString* RedirectionIdentifier() const; |
1590 void SetRedirectionIdentifier(const String& identifier) const; | 1603 void SetRedirectionIdentifier(const String& identifier) const; |
1591 RawFunction* RedirectionTarget() const; | 1604 RawFunction* RedirectionTarget() const; |
1592 void SetRedirectionTarget(const Function& target) const; | 1605 void SetRedirectionTarget(const Function& target) const; |
1593 | 1606 |
1594 RawFunction::Kind kind() const { | 1607 RawFunction::Kind kind() const { |
1595 return KindBits::decode(raw_ptr()->kind_tag_); | 1608 return KindBits::decode(raw_ptr()->kind_tag_); |
1596 } | 1609 } |
1597 | 1610 |
| 1611 static const char* KindToCString(RawFunction::Kind kind); |
| 1612 |
1598 bool is_static() const { return StaticBit::decode(raw_ptr()->kind_tag_); } | 1613 bool is_static() const { return StaticBit::decode(raw_ptr()->kind_tag_); } |
1599 bool is_const() const { return ConstBit::decode(raw_ptr()->kind_tag_); } | 1614 bool is_const() const { return ConstBit::decode(raw_ptr()->kind_tag_); } |
1600 bool is_external() const { return ExternalBit::decode(raw_ptr()->kind_tag_); } | 1615 bool is_external() const { return ExternalBit::decode(raw_ptr()->kind_tag_); } |
1601 bool IsConstructor() const { | 1616 bool IsConstructor() const { |
1602 return (kind() == RawFunction::kConstructor) && !is_static(); | 1617 return (kind() == RawFunction::kConstructor) && !is_static(); |
1603 } | 1618 } |
1604 bool IsImplicitConstructor() const; | 1619 bool IsImplicitConstructor() const; |
1605 bool IsFactory() const { | 1620 bool IsFactory() const { |
1606 return (kind() == RawFunction::kConstructor) && is_static(); | 1621 return (kind() == RawFunction::kConstructor) && is_static(); |
1607 } | 1622 } |
(...skipping 1623 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3231 | 3246 |
3232 RawDeoptInfo* GetDeoptInfoAtPc(uword pc, intptr_t* deopt_reason) const; | 3247 RawDeoptInfo* GetDeoptInfoAtPc(uword pc, intptr_t* deopt_reason) const; |
3233 | 3248 |
3234 // Returns null if there is no static call at 'pc'. | 3249 // Returns null if there is no static call at 'pc'. |
3235 RawFunction* GetStaticCallTargetFunctionAt(uword pc) const; | 3250 RawFunction* GetStaticCallTargetFunctionAt(uword pc) const; |
3236 // Returns null if there is no static call at 'pc'. | 3251 // Returns null if there is no static call at 'pc'. |
3237 RawCode* GetStaticCallTargetCodeAt(uword pc) const; | 3252 RawCode* GetStaticCallTargetCodeAt(uword pc) const; |
3238 // Aborts if there is no static call at 'pc'. | 3253 // Aborts if there is no static call at 'pc'. |
3239 void SetStaticCallTargetCodeAt(uword pc, const Code& code) const; | 3254 void SetStaticCallTargetCodeAt(uword pc, const Code& code) const; |
3240 | 3255 |
3241 void Disassemble() const; | 3256 void Disassemble(DisassemblyFormatter* formatter = NULL) const; |
3242 | 3257 |
3243 class Comments : public ZoneAllocated { | 3258 class Comments : public ZoneAllocated { |
3244 public: | 3259 public: |
3245 static Comments& New(intptr_t count); | 3260 static Comments& New(intptr_t count); |
3246 | 3261 |
3247 intptr_t Length() const; | 3262 intptr_t Length() const; |
3248 | 3263 |
3249 void SetPCOffsetAt(intptr_t idx, intptr_t pc_offset); | 3264 void SetPCOffsetAt(intptr_t idx, intptr_t pc_offset); |
3250 void SetCommentAt(intptr_t idx, const String& comment); | 3265 void SetCommentAt(intptr_t idx, const String& comment); |
3251 | 3266 |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3357 class OptimizedBit : public BitField<bool, kOptimizedBit, 1> {}; | 3372 class OptimizedBit : public BitField<bool, kOptimizedBit, 1> {}; |
3358 class AliveBit : public BitField<bool, kAliveBit, 1> {}; | 3373 class AliveBit : public BitField<bool, kAliveBit, 1> {}; |
3359 | 3374 |
3360 // An object finder visitor interface. | 3375 // An object finder visitor interface. |
3361 class FindRawCodeVisitor : public FindObjectVisitor { | 3376 class FindRawCodeVisitor : public FindObjectVisitor { |
3362 public: | 3377 public: |
3363 explicit FindRawCodeVisitor(uword pc) | 3378 explicit FindRawCodeVisitor(uword pc) |
3364 : FindObjectVisitor(Isolate::Current()), pc_(pc) { } | 3379 : FindObjectVisitor(Isolate::Current()), pc_(pc) { } |
3365 virtual ~FindRawCodeVisitor() { } | 3380 virtual ~FindRawCodeVisitor() { } |
3366 | 3381 |
| 3382 virtual uword filter_addr() const { return pc_; } |
| 3383 |
3367 // Check if object matches find condition. | 3384 // Check if object matches find condition. |
3368 virtual bool FindObject(RawObject* obj); | 3385 virtual bool FindObject(RawObject* obj) const; |
3369 | 3386 |
3370 private: | 3387 private: |
3371 const uword pc_; | 3388 const uword pc_; |
3372 | 3389 |
3373 DISALLOW_COPY_AND_ASSIGN(FindRawCodeVisitor); | 3390 DISALLOW_COPY_AND_ASSIGN(FindRawCodeVisitor); |
3374 }; | 3391 }; |
3375 | 3392 |
3376 static const intptr_t kEntrySize = sizeof(int32_t); // NOLINT | 3393 static const intptr_t kEntrySize = sizeof(int32_t); // NOLINT |
3377 | 3394 |
3378 void set_instructions(RawInstructions* instructions) { | 3395 void set_instructions(RawInstructions* instructions) { |
(...skipping 1685 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5064 intptr_t dst_offset, | 5081 intptr_t dst_offset, |
5065 const uint16_t* characters, | 5082 const uint16_t* characters, |
5066 intptr_t len); | 5083 intptr_t len); |
5067 static void Copy(const String& dst, | 5084 static void Copy(const String& dst, |
5068 intptr_t dst_offset, | 5085 intptr_t dst_offset, |
5069 const String& src, | 5086 const String& src, |
5070 intptr_t src_offset, | 5087 intptr_t src_offset, |
5071 intptr_t len); | 5088 intptr_t len); |
5072 | 5089 |
5073 static RawString* EscapeSpecialCharacters(const String& str); | 5090 static RawString* EscapeSpecialCharacters(const String& str); |
5074 | 5091 static RawString* EncodeURI(const String& str); |
| 5092 static RawString* DecodeURI(const String& str); |
5075 static RawString* Concat(const String& str1, | 5093 static RawString* Concat(const String& str1, |
5076 const String& str2, | 5094 const String& str2, |
5077 Heap::Space space = Heap::kNew); | 5095 Heap::Space space = Heap::kNew); |
5078 static RawString* ConcatAll(const Array& strings, | 5096 static RawString* ConcatAll(const Array& strings, |
5079 Heap::Space space = Heap::kNew); | 5097 Heap::Space space = Heap::kNew); |
5080 // Concat all strings in 'strings' from 'start' to 'end' (excluding). | 5098 // Concat all strings in 'strings' from 'start' to 'end' (excluding). |
5081 static RawString* ConcatAllRange(const Array& strings, | 5099 static RawString* ConcatAllRange(const Array& strings, |
5082 intptr_t start, | 5100 intptr_t start, |
5083 intptr_t end, | 5101 intptr_t end, |
5084 Heap::Space space = Heap::kNew); | 5102 Heap::Space space = Heap::kNew); |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5155 class OneByteString : public AllStatic { | 5173 class OneByteString : public AllStatic { |
5156 public: | 5174 public: |
5157 static int32_t CharAt(const String& str, intptr_t index) { | 5175 static int32_t CharAt(const String& str, intptr_t index) { |
5158 return *CharAddr(str, index); | 5176 return *CharAddr(str, index); |
5159 } | 5177 } |
5160 | 5178 |
5161 static void SetCharAt(const String& str, intptr_t index, uint8_t code_point) { | 5179 static void SetCharAt(const String& str, intptr_t index, uint8_t code_point) { |
5162 *CharAddr(str, index) = code_point; | 5180 *CharAddr(str, index) = code_point; |
5163 } | 5181 } |
5164 static RawOneByteString* EscapeSpecialCharacters(const String& str); | 5182 static RawOneByteString* EscapeSpecialCharacters(const String& str); |
5165 | |
5166 // We use the same maximum elements for all strings. | 5183 // We use the same maximum elements for all strings. |
5167 static const intptr_t kBytesPerElement = 1; | 5184 static const intptr_t kBytesPerElement = 1; |
5168 static const intptr_t kMaxElements = String::kMaxElements; | 5185 static const intptr_t kMaxElements = String::kMaxElements; |
5169 | 5186 |
5170 static intptr_t data_offset() { return OFFSET_OF(RawOneByteString, data_); } | 5187 static intptr_t data_offset() { return OFFSET_OF(RawOneByteString, data_); } |
5171 | 5188 |
5172 static intptr_t InstanceSize() { | 5189 static intptr_t InstanceSize() { |
5173 ASSERT(sizeof(RawOneByteString) == OFFSET_OF(RawOneByteString, data_)); | 5190 ASSERT(sizeof(RawOneByteString) == OFFSET_OF(RawOneByteString, data_)); |
5174 return 0; | 5191 return 0; |
5175 } | 5192 } |
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5379 intptr_t len, | 5396 intptr_t len, |
5380 void* peer, | 5397 void* peer, |
5381 Dart_PeerFinalizer callback, | 5398 Dart_PeerFinalizer callback, |
5382 Heap::Space space); | 5399 Heap::Space space); |
5383 | 5400 |
5384 static RawExternalOneByteString* null() { | 5401 static RawExternalOneByteString* null() { |
5385 return reinterpret_cast<RawExternalOneByteString*>(Object::null()); | 5402 return reinterpret_cast<RawExternalOneByteString*>(Object::null()); |
5386 } | 5403 } |
5387 | 5404 |
5388 static RawOneByteString* EscapeSpecialCharacters(const String& str); | 5405 static RawOneByteString* EscapeSpecialCharacters(const String& str); |
| 5406 static RawOneByteString* EncodeURI(const String& str); |
| 5407 static RawOneByteString* DecodeURI(const String& str); |
5389 | 5408 |
5390 static const ClassId kClassId = kExternalOneByteStringCid; | 5409 static const ClassId kClassId = kExternalOneByteStringCid; |
5391 | 5410 |
5392 private: | 5411 private: |
5393 static RawExternalOneByteString* raw(const String& str) { | 5412 static RawExternalOneByteString* raw(const String& str) { |
5394 return reinterpret_cast<RawExternalOneByteString*>(str.raw()); | 5413 return reinterpret_cast<RawExternalOneByteString*>(str.raw()); |
5395 } | 5414 } |
5396 | 5415 |
5397 static RawExternalOneByteString* raw_ptr(const String& str) { | 5416 static RawExternalOneByteString* raw_ptr(const String& str) { |
5398 return reinterpret_cast<RawExternalOneByteString*>(str.raw_ptr()); | 5417 return reinterpret_cast<RawExternalOneByteString*>(str.raw_ptr()); |
(...skipping 1164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6563 | 6582 |
6564 | 6583 |
6565 RawObject* MegamorphicCache::GetTargetFunction(const Array& array, | 6584 RawObject* MegamorphicCache::GetTargetFunction(const Array& array, |
6566 intptr_t index) { | 6585 intptr_t index) { |
6567 return array.At((index * kEntryLength) + kTargetFunctionIndex); | 6586 return array.At((index * kEntryLength) + kTargetFunctionIndex); |
6568 } | 6587 } |
6569 | 6588 |
6570 } // namespace dart | 6589 } // namespace dart |
6571 | 6590 |
6572 #endif // VM_OBJECT_H_ | 6591 #endif // VM_OBJECT_H_ |
OLD | NEW |