OLD | NEW |
1 // Copyright 2007-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2007-2009 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 3282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3293 // Tag information for HeapObject. | 3293 // Tag information for HeapObject. |
3294 const int kHeapObjectTag = 1; | 3294 const int kHeapObjectTag = 1; |
3295 const int kHeapObjectTagSize = 2; | 3295 const int kHeapObjectTagSize = 2; |
3296 const intptr_t kHeapObjectTagMask = (1 << kHeapObjectTagSize) - 1; | 3296 const intptr_t kHeapObjectTagMask = (1 << kHeapObjectTagSize) - 1; |
3297 | 3297 |
3298 // Tag information for Smi. | 3298 // Tag information for Smi. |
3299 const int kSmiTag = 0; | 3299 const int kSmiTag = 0; |
3300 const int kSmiTagSize = 1; | 3300 const int kSmiTagSize = 1; |
3301 const intptr_t kSmiTagMask = (1 << kSmiTagSize) - 1; | 3301 const intptr_t kSmiTagMask = (1 << kSmiTagSize) - 1; |
3302 | 3302 |
3303 template <size_t ptr_size> struct SmiConstants; | 3303 template <size_t ptr_size> struct SmiTagging; |
3304 | 3304 |
3305 // Smi constants for 32-bit systems. | 3305 // Smi constants for 32-bit systems. |
3306 template <> struct SmiConstants<4> { | 3306 template <> struct SmiTagging<4> { |
3307 static const int kSmiShiftSize = 0; | 3307 static const int kSmiShiftSize = 0; |
3308 static const int kSmiValueSize = 31; | 3308 static const int kSmiValueSize = 31; |
3309 static inline int SmiToInt(internal::Object* value) { | 3309 static inline int SmiToInt(internal::Object* value) { |
3310 int shift_bits = kSmiTagSize + kSmiShiftSize; | 3310 int shift_bits = kSmiTagSize + kSmiShiftSize; |
3311 // Throw away top 32 bits and shift down (requires >> to be sign extending). | 3311 // Throw away top 32 bits and shift down (requires >> to be sign extending). |
3312 return static_cast<int>(reinterpret_cast<intptr_t>(value)) >> shift_bits; | 3312 return static_cast<int>(reinterpret_cast<intptr_t>(value)) >> shift_bits; |
3313 } | 3313 } |
| 3314 |
| 3315 // For 32-bit systems any 2 bytes aligned pointer can be encoded as smi |
| 3316 // with a plain reinterpret_cast. |
| 3317 static const intptr_t kEncodablePointerMask = 0x1; |
| 3318 static const int kPointerToSmiShift = 0; |
3314 }; | 3319 }; |
3315 | 3320 |
3316 // Smi constants for 64-bit systems. | 3321 // Smi constants for 64-bit systems. |
3317 template <> struct SmiConstants<8> { | 3322 template <> struct SmiTagging<8> { |
3318 static const int kSmiShiftSize = 31; | 3323 static const int kSmiShiftSize = 31; |
3319 static const int kSmiValueSize = 32; | 3324 static const int kSmiValueSize = 32; |
3320 static inline int SmiToInt(internal::Object* value) { | 3325 static inline int SmiToInt(internal::Object* value) { |
3321 int shift_bits = kSmiTagSize + kSmiShiftSize; | 3326 int shift_bits = kSmiTagSize + kSmiShiftSize; |
3322 // Shift down and throw away top 32 bits. | 3327 // Shift down and throw away top 32 bits. |
3323 return static_cast<int>(reinterpret_cast<intptr_t>(value) >> shift_bits); | 3328 return static_cast<int>(reinterpret_cast<intptr_t>(value) >> shift_bits); |
3324 } | 3329 } |
| 3330 |
| 3331 // To maximize the range of pointers that can be encoded |
| 3332 // in the available 32 bits, we require them to be 8 bytes aligned. |
| 3333 // This gives 2 ^ (32 + 3) = 32G address space covered. |
| 3334 // It might be not enough to cover stack allocated objects on some platforms. |
| 3335 static const int kPointerAlignment = 3; |
| 3336 |
| 3337 static const intptr_t kEncodablePointerMask = |
| 3338 ~(intptr_t(0xffffffff) << kPointerAlignment); |
| 3339 |
| 3340 static const int kPointerToSmiShift = |
| 3341 kSmiTagSize + kSmiShiftSize - kPointerAlignment; |
3325 }; | 3342 }; |
3326 | 3343 |
3327 const int kSmiShiftSize = SmiConstants<kApiPointerSize>::kSmiShiftSize; | 3344 typedef SmiTagging<kApiPointerSize> PlatformSmiTagging; |
3328 const int kSmiValueSize = SmiConstants<kApiPointerSize>::kSmiValueSize; | 3345 const int kSmiShiftSize = PlatformSmiTagging::kSmiShiftSize; |
| 3346 const int kSmiValueSize = PlatformSmiTagging::kSmiValueSize; |
| 3347 const intptr_t kEncodablePointerMask = |
| 3348 PlatformSmiTagging::kEncodablePointerMask; |
| 3349 const int kPointerToSmiShift = PlatformSmiTagging::kPointerToSmiShift; |
3329 | 3350 |
3330 template <size_t ptr_size> struct InternalConstants; | 3351 template <size_t ptr_size> struct InternalConstants; |
3331 | 3352 |
3332 // Internal constants for 32-bit systems. | 3353 // Internal constants for 32-bit systems. |
3333 template <> struct InternalConstants<4> { | 3354 template <> struct InternalConstants<4> { |
3334 static const int kStringResourceOffset = 3 * kApiPointerSize; | 3355 static const int kStringResourceOffset = 3 * kApiPointerSize; |
3335 }; | 3356 }; |
3336 | 3357 |
3337 // Internal constants for 64-bit systems. | 3358 // Internal constants for 64-bit systems. |
3338 template <> struct InternalConstants<8> { | 3359 template <> struct InternalConstants<8> { |
(...skipping 27 matching lines...) Expand all Loading... |
3366 static inline bool HasHeapObjectTag(internal::Object* value) { | 3387 static inline bool HasHeapObjectTag(internal::Object* value) { |
3367 return ((reinterpret_cast<intptr_t>(value) & kHeapObjectTagMask) == | 3388 return ((reinterpret_cast<intptr_t>(value) & kHeapObjectTagMask) == |
3368 kHeapObjectTag); | 3389 kHeapObjectTag); |
3369 } | 3390 } |
3370 | 3391 |
3371 static inline bool HasSmiTag(internal::Object* value) { | 3392 static inline bool HasSmiTag(internal::Object* value) { |
3372 return ((reinterpret_cast<intptr_t>(value) & kSmiTagMask) == kSmiTag); | 3393 return ((reinterpret_cast<intptr_t>(value) & kSmiTagMask) == kSmiTag); |
3373 } | 3394 } |
3374 | 3395 |
3375 static inline int SmiValue(internal::Object* value) { | 3396 static inline int SmiValue(internal::Object* value) { |
3376 return SmiConstants<kApiPointerSize>::SmiToInt(value); | 3397 return PlatformSmiTagging::SmiToInt(value); |
3377 } | 3398 } |
3378 | 3399 |
3379 static inline int GetInstanceType(internal::Object* obj) { | 3400 static inline int GetInstanceType(internal::Object* obj) { |
3380 typedef internal::Object O; | 3401 typedef internal::Object O; |
3381 O* map = ReadField<O*>(obj, kHeapObjectMapOffset); | 3402 O* map = ReadField<O*>(obj, kHeapObjectMapOffset); |
3382 return ReadField<uint8_t>(map, kMapInstanceTypeOffset); | 3403 return ReadField<uint8_t>(map, kMapInstanceTypeOffset); |
3383 } | 3404 } |
3384 | 3405 |
| 3406 static inline void* GetExternalPointerFromSmi(internal::Object* value) { |
| 3407 const intptr_t address = reinterpret_cast<intptr_t>(value); |
| 3408 return reinterpret_cast<void*>(address >> kPointerToSmiShift); |
| 3409 } |
| 3410 |
3385 static inline void* GetExternalPointer(internal::Object* obj) { | 3411 static inline void* GetExternalPointer(internal::Object* obj) { |
3386 if (HasSmiTag(obj)) { | 3412 if (HasSmiTag(obj)) { |
3387 return obj; | 3413 return GetExternalPointerFromSmi(obj); |
3388 } else if (GetInstanceType(obj) == kProxyType) { | 3414 } else if (GetInstanceType(obj) == kProxyType) { |
3389 return ReadField<void*>(obj, kProxyProxyOffset); | 3415 return ReadField<void*>(obj, kProxyProxyOffset); |
3390 } else { | 3416 } else { |
3391 return NULL; | 3417 return NULL; |
3392 } | 3418 } |
3393 } | 3419 } |
3394 | 3420 |
3395 static inline bool IsExternalTwoByteString(int instance_type) { | 3421 static inline bool IsExternalTwoByteString(int instance_type) { |
3396 int representation = (instance_type & kFullStringRepresentationMask); | 3422 int representation = (instance_type & kFullStringRepresentationMask); |
3397 return representation == kExternalTwoByteRepresentationTag; | 3423 return representation == kExternalTwoByteRepresentationTag; |
(...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3744 | 3770 |
3745 | 3771 |
3746 } // namespace v8 | 3772 } // namespace v8 |
3747 | 3773 |
3748 | 3774 |
3749 #undef V8EXPORT | 3775 #undef V8EXPORT |
3750 #undef TYPE_CHECK | 3776 #undef TYPE_CHECK |
3751 | 3777 |
3752 | 3778 |
3753 #endif // V8_H_ | 3779 #endif // V8_H_ |
OLD | NEW |