Index: include/v8.h |
diff --git a/include/v8.h b/include/v8.h |
index 3a9827b24d3ba2e361c4ba326446fdd87ebee314..7d18107d92d228c8f6de6e6d519d524e0f5de8ce 100644 |
--- a/include/v8.h |
+++ b/include/v8.h |
@@ -3353,10 +3353,10 @@ const int kSmiTag = 0; |
const int kSmiTagSize = 1; |
const intptr_t kSmiTagMask = (1 << kSmiTagSize) - 1; |
-template <size_t ptr_size> struct SmiConstants; |
+template <size_t ptr_size> struct SmiTagging; |
// Smi constants for 32-bit systems. |
-template <> struct SmiConstants<4> { |
+template <> struct SmiTagging<4> { |
static const int kSmiShiftSize = 0; |
static const int kSmiValueSize = 31; |
static inline int SmiToInt(internal::Object* value) { |
@@ -3364,10 +3364,15 @@ template <> struct SmiConstants<4> { |
// Throw away top 32 bits and shift down (requires >> to be sign extending). |
return static_cast<int>(reinterpret_cast<intptr_t>(value)) >> shift_bits; |
} |
+ |
+ // For 32-bit systems any 2 bytes aligned pointer can be encoded as smi |
+ // with a plain reinterpret_cast. |
+ static const intptr_t kEncodablePointerMask = 0x1; |
+ static const int kPointerToSmiShift = 0; |
}; |
// Smi constants for 64-bit systems. |
-template <> struct SmiConstants<8> { |
+template <> struct SmiTagging<8> { |
static const int kSmiShiftSize = 31; |
static const int kSmiValueSize = 32; |
static inline int SmiToInt(internal::Object* value) { |
@@ -3375,10 +3380,26 @@ template <> struct SmiConstants<8> { |
// Shift down and throw away top 32 bits. |
return static_cast<int>(reinterpret_cast<intptr_t>(value) >> shift_bits); |
} |
+ |
+ // To maximize the range of pointers that can be encoded |
+ // in the available 32 bits, we require them to be 8 bytes aligned. |
+ // This gives 2 ^ (32 + 3) = 32G address space covered. |
+ // It might be not enough to cover stack allocated objects on some platforms. |
+ static const int kPointerAlignment = 3; |
+ |
+ static const intptr_t kEncodablePointerMask = |
+ ~(intptr_t(0xffffffff) << kPointerAlignment); |
+ |
+ static const int kPointerToSmiShift = |
+ kSmiTagSize + kSmiShiftSize - kPointerAlignment; |
}; |
-const int kSmiShiftSize = SmiConstants<kApiPointerSize>::kSmiShiftSize; |
-const int kSmiValueSize = SmiConstants<kApiPointerSize>::kSmiValueSize; |
+typedef SmiTagging<kApiPointerSize> PlatformSmiTagging; |
+const int kSmiShiftSize = PlatformSmiTagging::kSmiShiftSize; |
+const int kSmiValueSize = PlatformSmiTagging::kSmiValueSize; |
+const intptr_t kEncodablePointerMask = |
+ PlatformSmiTagging::kEncodablePointerMask; |
+const int kPointerToSmiShift = PlatformSmiTagging::kPointerToSmiShift; |
template <size_t ptr_size> struct InternalConstants; |
@@ -3426,7 +3447,7 @@ class Internals { |
} |
static inline int SmiValue(internal::Object* value) { |
- return SmiConstants<kApiPointerSize>::SmiToInt(value); |
+ return PlatformSmiTagging::SmiToInt(value); |
} |
static inline int GetInstanceType(internal::Object* obj) { |
@@ -3435,9 +3456,14 @@ class Internals { |
return ReadField<uint8_t>(map, kMapInstanceTypeOffset); |
} |
+ static inline void* GetExternalPointerFromSmi(internal::Object* value) { |
+ const intptr_t address = reinterpret_cast<intptr_t>(value); |
+ return reinterpret_cast<void*>(address >> kPointerToSmiShift); |
+ } |
+ |
static inline void* GetExternalPointer(internal::Object* obj) { |
if (HasSmiTag(obj)) { |
- return obj; |
+ return GetExternalPointerFromSmi(obj); |
} else if (GetInstanceType(obj) == kProxyType) { |
return ReadField<void*>(obj, kProxyProxyOffset); |
} else { |