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 3335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3346 // Tag information for HeapObject. | 3346 // Tag information for HeapObject. |
3347 const int kHeapObjectTag = 1; | 3347 const int kHeapObjectTag = 1; |
3348 const int kHeapObjectTagSize = 2; | 3348 const int kHeapObjectTagSize = 2; |
3349 const intptr_t kHeapObjectTagMask = (1 << kHeapObjectTagSize) - 1; | 3349 const intptr_t kHeapObjectTagMask = (1 << kHeapObjectTagSize) - 1; |
3350 | 3350 |
3351 // Tag information for Smi. | 3351 // Tag information for Smi. |
3352 const int kSmiTag = 0; | 3352 const int kSmiTag = 0; |
3353 const int kSmiTagSize = 1; | 3353 const int kSmiTagSize = 1; |
3354 const intptr_t kSmiTagMask = (1 << kSmiTagSize) - 1; | 3354 const intptr_t kSmiTagMask = (1 << kSmiTagSize) - 1; |
3355 | 3355 |
3356 template <size_t ptr_size> struct SmiConstants; | 3356 template <size_t ptr_size> struct SmiTagging; |
3357 | 3357 |
3358 // Smi constants for 32-bit systems. | 3358 // Smi constants for 32-bit systems. |
3359 template <> struct SmiConstants<4> { | 3359 template <> struct SmiTagging<4> { |
3360 static const int kSmiShiftSize = 0; | 3360 static const int kSmiShiftSize = 0; |
3361 static const int kSmiValueSize = 31; | 3361 static const int kSmiValueSize = 31; |
3362 static inline int SmiToInt(internal::Object* value) { | 3362 static inline int SmiToInt(internal::Object* value) { |
3363 int shift_bits = kSmiTagSize + kSmiShiftSize; | 3363 int shift_bits = kSmiTagSize + kSmiShiftSize; |
3364 // Throw away top 32 bits and shift down (requires >> to be sign extending). | 3364 // Throw away top 32 bits and shift down (requires >> to be sign extending). |
3365 return static_cast<int>(reinterpret_cast<intptr_t>(value)) >> shift_bits; | 3365 return static_cast<int>(reinterpret_cast<intptr_t>(value)) >> shift_bits; |
3366 } | 3366 } |
| 3367 |
| 3368 // For 32-bit systems any 2 bytes aligned pointer can be encoded as smi |
| 3369 // with a plain reinterpret_cast. |
| 3370 static const intptr_t kEncodablePointerMask = 0x1; |
| 3371 static const int kPointerToSmiShift = 0; |
3367 }; | 3372 }; |
3368 | 3373 |
3369 // Smi constants for 64-bit systems. | 3374 // Smi constants for 64-bit systems. |
3370 template <> struct SmiConstants<8> { | 3375 template <> struct SmiTagging<8> { |
3371 static const int kSmiShiftSize = 31; | 3376 static const int kSmiShiftSize = 31; |
3372 static const int kSmiValueSize = 32; | 3377 static const int kSmiValueSize = 32; |
3373 static inline int SmiToInt(internal::Object* value) { | 3378 static inline int SmiToInt(internal::Object* value) { |
3374 int shift_bits = kSmiTagSize + kSmiShiftSize; | 3379 int shift_bits = kSmiTagSize + kSmiShiftSize; |
3375 // Shift down and throw away top 32 bits. | 3380 // Shift down and throw away top 32 bits. |
3376 return static_cast<int>(reinterpret_cast<intptr_t>(value) >> shift_bits); | 3381 return static_cast<int>(reinterpret_cast<intptr_t>(value) >> shift_bits); |
3377 } | 3382 } |
| 3383 |
| 3384 // To maximize the range of pointers that can be encoded |
| 3385 // in the available 32 bits, we require them to be 8 bytes aligned. |
| 3386 // This gives 2 ^ (32 + 3) = 32G address space covered. |
| 3387 // It might be not enough to cover stack allocated objects on some platforms. |
| 3388 static const int kPointerAlignment = 3; |
| 3389 |
| 3390 static const intptr_t kEncodablePointerMask = |
| 3391 ~(intptr_t(0xffffffff) << kPointerAlignment); |
| 3392 |
| 3393 static const int kPointerToSmiShift = |
| 3394 kSmiTagSize + kSmiShiftSize - kPointerAlignment; |
3378 }; | 3395 }; |
3379 | 3396 |
3380 const int kSmiShiftSize = SmiConstants<kApiPointerSize>::kSmiShiftSize; | 3397 typedef SmiTagging<kApiPointerSize> PlatformSmiTagging; |
3381 const int kSmiValueSize = SmiConstants<kApiPointerSize>::kSmiValueSize; | 3398 const int kSmiShiftSize = PlatformSmiTagging::kSmiShiftSize; |
| 3399 const int kSmiValueSize = PlatformSmiTagging::kSmiValueSize; |
| 3400 const intptr_t kEncodablePointerMask = |
| 3401 PlatformSmiTagging::kEncodablePointerMask; |
| 3402 const int kPointerToSmiShift = PlatformSmiTagging::kPointerToSmiShift; |
3382 | 3403 |
3383 template <size_t ptr_size> struct InternalConstants; | 3404 template <size_t ptr_size> struct InternalConstants; |
3384 | 3405 |
3385 // Internal constants for 32-bit systems. | 3406 // Internal constants for 32-bit systems. |
3386 template <> struct InternalConstants<4> { | 3407 template <> struct InternalConstants<4> { |
3387 static const int kStringResourceOffset = 3 * kApiPointerSize; | 3408 static const int kStringResourceOffset = 3 * kApiPointerSize; |
3388 }; | 3409 }; |
3389 | 3410 |
3390 // Internal constants for 64-bit systems. | 3411 // Internal constants for 64-bit systems. |
3391 template <> struct InternalConstants<8> { | 3412 template <> struct InternalConstants<8> { |
(...skipping 27 matching lines...) Expand all Loading... |
3419 static inline bool HasHeapObjectTag(internal::Object* value) { | 3440 static inline bool HasHeapObjectTag(internal::Object* value) { |
3420 return ((reinterpret_cast<intptr_t>(value) & kHeapObjectTagMask) == | 3441 return ((reinterpret_cast<intptr_t>(value) & kHeapObjectTagMask) == |
3421 kHeapObjectTag); | 3442 kHeapObjectTag); |
3422 } | 3443 } |
3423 | 3444 |
3424 static inline bool HasSmiTag(internal::Object* value) { | 3445 static inline bool HasSmiTag(internal::Object* value) { |
3425 return ((reinterpret_cast<intptr_t>(value) & kSmiTagMask) == kSmiTag); | 3446 return ((reinterpret_cast<intptr_t>(value) & kSmiTagMask) == kSmiTag); |
3426 } | 3447 } |
3427 | 3448 |
3428 static inline int SmiValue(internal::Object* value) { | 3449 static inline int SmiValue(internal::Object* value) { |
3429 return SmiConstants<kApiPointerSize>::SmiToInt(value); | 3450 return PlatformSmiTagging::SmiToInt(value); |
3430 } | 3451 } |
3431 | 3452 |
3432 static inline int GetInstanceType(internal::Object* obj) { | 3453 static inline int GetInstanceType(internal::Object* obj) { |
3433 typedef internal::Object O; | 3454 typedef internal::Object O; |
3434 O* map = ReadField<O*>(obj, kHeapObjectMapOffset); | 3455 O* map = ReadField<O*>(obj, kHeapObjectMapOffset); |
3435 return ReadField<uint8_t>(map, kMapInstanceTypeOffset); | 3456 return ReadField<uint8_t>(map, kMapInstanceTypeOffset); |
3436 } | 3457 } |
3437 | 3458 |
| 3459 static inline void* GetExternalPointerFromSmi(internal::Object* value) { |
| 3460 const intptr_t address = reinterpret_cast<intptr_t>(value); |
| 3461 return reinterpret_cast<void*>(address >> kPointerToSmiShift); |
| 3462 } |
| 3463 |
3438 static inline void* GetExternalPointer(internal::Object* obj) { | 3464 static inline void* GetExternalPointer(internal::Object* obj) { |
3439 if (HasSmiTag(obj)) { | 3465 if (HasSmiTag(obj)) { |
3440 return obj; | 3466 return GetExternalPointerFromSmi(obj); |
3441 } else if (GetInstanceType(obj) == kProxyType) { | 3467 } else if (GetInstanceType(obj) == kProxyType) { |
3442 return ReadField<void*>(obj, kProxyProxyOffset); | 3468 return ReadField<void*>(obj, kProxyProxyOffset); |
3443 } else { | 3469 } else { |
3444 return NULL; | 3470 return NULL; |
3445 } | 3471 } |
3446 } | 3472 } |
3447 | 3473 |
3448 static inline bool IsExternalTwoByteString(int instance_type) { | 3474 static inline bool IsExternalTwoByteString(int instance_type) { |
3449 int representation = (instance_type & kFullStringRepresentationMask); | 3475 int representation = (instance_type & kFullStringRepresentationMask); |
3450 return representation == kExternalTwoByteRepresentationTag; | 3476 return representation == kExternalTwoByteRepresentationTag; |
(...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3797 | 3823 |
3798 | 3824 |
3799 } // namespace v8 | 3825 } // namespace v8 |
3800 | 3826 |
3801 | 3827 |
3802 #undef V8EXPORT | 3828 #undef V8EXPORT |
3803 #undef TYPE_CHECK | 3829 #undef TYPE_CHECK |
3804 | 3830 |
3805 | 3831 |
3806 #endif // V8_H_ | 3832 #endif // V8_H_ |
OLD | NEW |