v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
smi.h
Go to the documentation of this file.
1// Copyright 2018 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef V8_OBJECTS_SMI_H_
6#define V8_OBJECTS_SMI_H_
7
8#include <type_traits>
9
10#include "src/common/globals.h"
11#include "src/objects/tagged.h"
12
13// Has to be the last include (doesn't have include guards):
15
16namespace v8 {
17namespace internal {
18
19// Smi represents integer Numbers that can be stored in 31 bits.
20// Smis are immediate which means they are NOT allocated in the heap.
21// The ptr_ value has the following format: [31 bit signed int] 0
22// For long smis it has the following format:
23// [32 bit signed int] [31 bits zero padding] 0
24// Smi stands for small integer.
25class Smi : public AllStatic {
26 public:
27 static inline constexpr Tagged<Smi> ToUint32Smi(Tagged<Smi> smi) {
28 if (smi.value() <= 0) return Smi::FromInt(0);
29 return Smi::FromInt(static_cast<uint32_t>(smi.value()));
30 }
31
32 // Convert a Smi object to an int.
33 static inline constexpr int ToInt(const Tagged<Object> object) {
34 return Tagged<Smi>(object.ptr()).value();
35 }
36
37 // Convert a value to a Smi object.
38 static inline constexpr Tagged<Smi> FromInt(int value) {
39 DCHECK(Smi::IsValid(value));
41 }
42
43 static inline constexpr Tagged<Smi> FromIntptr(intptr_t value) {
44 DCHECK(Smi::IsValid(value));
45 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
46 return Tagged<Smi>((static_cast<Address>(value) << smi_shift_bits) |
47 kSmiTag);
48 }
49
50 // Given {value} in [0, 2^31-1], force it into Smi range by changing at most
51 // the MSB (leaving the lower 31 bit unchanged).
52 static inline constexpr Tagged<Smi> From31BitPattern(int value) {
53 return Smi::FromInt((value << (32 - kSmiValueSize)) >>
54 (32 - kSmiValueSize));
55 }
56
57 template <typename E>
58 static inline constexpr Tagged<Smi> FromEnum(E value)
59 requires std::is_enum<E>::value
60 {
61 static_assert(sizeof(E) <= sizeof(int));
62 return FromInt(static_cast<int>(value));
63 }
64
65 // Returns whether value can be represented in a Smi.
66 template <typename T>
67 static inline bool constexpr IsValid(T value)
68 requires(std::is_integral_v<T> && std::is_signed_v<T>)
69 {
71 value >= kMinValue && value <= kMaxValue);
72 return Internals::IsValidSmi(value);
73 }
74 template <typename T>
75 static inline bool constexpr IsValid(T value)
76 requires(std::is_integral_v<T> && std::is_unsigned_v<T>)
77 {
79 return Internals::IsValidSmi(value);
80 }
81
82 // Compare two Smis x, y as if they were converted to strings and then
83 // compared lexicographically. Returns:
84 // -1 if x < y.
85 // 0 if x == y.
86 // 1 if x > y.
87 // Returns the result (a tagged Smi) as a raw Address for ExternalReference
88 // usage.
92
93 // Dispatched behavior.
94 V8_EXPORT_PRIVATE static void SmiPrint(Tagged<Smi> smi, std::ostream& os);
96
97 // Since this is a constexpr, "calling" it is just as efficient
98 // as reading a constant.
99 static inline constexpr Tagged<Smi> zero() { return Smi::FromInt(0); }
100 static constexpr int kMinValue = kSmiMinValue;
101 static constexpr int kMaxValue = kSmiMaxValue;
102
103 // Smi value for filling in not-yet initialized tagged field values with a
104 // valid tagged pointer. A field value equal to this doesn't necessarily
105 // indicate that a field is uninitialized, but an uninitialized field should
106 // definitely equal this value.
107 //
108 // This _has_ to be kNullAddress, so that an uninitialized field value read as
109 // an embedded pointer field is interpreted as nullptr. This is so that
110 // uninitialised embedded pointers are not forwarded to the embedder as part
111 // of embedder tracing (and similar mechanisms), as nullptrs are skipped for
112 // those cases and otherwise the embedder would try to dereference the
113 // uninitialized pointer value.
117};
118
119} // namespace internal
120} // namespace v8
121
123
124#endif // V8_OBJECTS_SMI_H_
static V8_INLINE constexpr Address IntegralToSmi(T value)
static V8_INLINE constexpr bool IsValidSmi(T value)
static constexpr Tagged< Smi > FromEnum(E value)
Definition smi.h:58
static constexpr int ToInt(const Tagged< Object > object)
Definition smi.h:33
static constexpr Tagged< Smi > uninitialized_deserialization_value()
Definition smi.h:114
static constexpr Tagged< Smi > FromInt(int value)
Definition smi.h:38
static bool constexpr IsValid(T value)
Definition smi.h:75
static constexpr Tagged< Smi > From31BitPattern(int value)
Definition smi.h:52
static constexpr Tagged< Smi > FromIntptr(intptr_t value)
Definition smi.h:43
static bool constexpr IsValid(T value)
Definition smi.h:67
static constexpr Tagged< Smi > ToUint32Smi(Tagged< Smi > smi)
Definition smi.h:27
static constexpr int kMinValue
Definition smi.h:100
static V8_EXPORT_PRIVATE Address LexicographicCompare(Isolate *isolate, Tagged< Smi > x, Tagged< Smi > y)
Definition objects.cc:6618
static V8_EXPORT_PRIVATE void SmiPrint(Tagged< Smi > smi, std::ostream &os)
Definition objects.cc:1913
static constexpr int kMaxValue
Definition smi.h:101
int x
const int kSmiTagSize
Definition v8-internal.h:87
const int kSmiShiftSize
const int kSmiValueSize
const int kSmiMaxValue
const int kSmiTag
Definition v8-internal.h:86
static constexpr Address kNullAddress
Definition v8-internal.h:53
const int kSmiMinValue
#define DECL_STATIC_VERIFIER(Name)
#define DCHECK(condition)
Definition logging.h:482
#define DCHECK_EQ(v1, v2)
Definition logging.h:485
#define V8_EXPORT_PRIVATE
Definition macros.h:460