• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 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_TYPES_INL_H_
6 #define V8_TYPES_INL_H_
7 
8 #include "src/types.h"
9 
10 #include "src/factory.h"
11 #include "src/handles-inl.h"
12 
13 namespace v8 {
14 namespace internal {
15 
16 // -----------------------------------------------------------------------------
17 // TypeImpl
18 
19 template<class Config>
SignedSmall()20 typename TypeImpl<Config>::bitset TypeImpl<Config>::BitsetType::SignedSmall() {
21   return i::SmiValuesAre31Bits() ? kSigned31 : kSigned32;
22 }
23 
24 
25 template<class Config>
26 typename TypeImpl<Config>::bitset
UnsignedSmall()27 TypeImpl<Config>::BitsetType::UnsignedSmall() {
28   return i::SmiValuesAre31Bits() ? kUnsigned30 : kUnsigned31;
29 }
30 
31 
32 #define CONSTRUCT_SIMD_TYPE(NAME, Name, name, lane_count, lane_type) \
33 template<class Config> \
34 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Name( \
35     Isolate* isolate, Region* region) { \
36   return Class(i::handle(isolate->heap()->name##_map()), region); \
37 }
SIMD128_TYPES(CONSTRUCT_SIMD_TYPE)38 SIMD128_TYPES(CONSTRUCT_SIMD_TYPE)
39 #undef CONSTRUCT_SIMD_TYPE
40 
41 
42 template<class Config>
43 TypeImpl<Config>* TypeImpl<Config>::cast(typename Config::Base* object) {
44   TypeImpl* t = static_cast<TypeImpl*>(object);
45   DCHECK(t->IsBitset() || t->IsClass() || t->IsConstant() || t->IsRange() ||
46          t->IsUnion() || t->IsArray() || t->IsFunction() || t->IsContext());
47   return t;
48 }
49 
50 
51 // Most precise _current_ type of a value (usually its class).
52 template<class Config>
NowOf(i::Object * value,Region * region)53 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::NowOf(
54     i::Object* value, Region* region) {
55   if (value->IsSmi() ||
56       i::HeapObject::cast(value)->map()->instance_type() == HEAP_NUMBER_TYPE) {
57     return Of(value, region);
58   }
59   return Class(i::handle(i::HeapObject::cast(value)->map()), region);
60 }
61 
62 
63 template<class Config>
NowContains(i::Object * value)64 bool TypeImpl<Config>::NowContains(i::Object* value) {
65   DisallowHeapAllocation no_allocation;
66   if (this->IsAny()) return true;
67   if (value->IsHeapObject()) {
68     i::Map* map = i::HeapObject::cast(value)->map();
69     for (Iterator<i::Map> it = this->Classes(); !it.Done(); it.Advance()) {
70       if (*it.Current() == map) return true;
71     }
72   }
73   return this->Contains(value);
74 }
75 
76 
77 // -----------------------------------------------------------------------------
78 // ZoneTypeConfig
79 
80 // static
81 template<class T>
handle(T * type)82 T* ZoneTypeConfig::handle(T* type) {
83   return type;
84 }
85 
86 
87 // static
88 template<class T>
cast(Type * type)89 T* ZoneTypeConfig::cast(Type* type) {
90   return static_cast<T*>(type);
91 }
92 
93 
94 // static
is_bitset(Type * type)95 bool ZoneTypeConfig::is_bitset(Type* type) {
96   return reinterpret_cast<uintptr_t>(type) & 1;
97 }
98 
99 
100 // static
is_struct(Type * type,int tag)101 bool ZoneTypeConfig::is_struct(Type* type, int tag) {
102   DCHECK(tag != kRangeStructTag);
103   if (is_bitset(type)) return false;
104   int type_tag = struct_tag(as_struct(type));
105   return type_tag == tag;
106 }
107 
108 
109 // static
is_range(Type * type)110 bool ZoneTypeConfig::is_range(Type* type) {
111   if (is_bitset(type)) return false;
112   int type_tag = struct_tag(as_struct(type));
113   return type_tag == kRangeStructTag;
114 }
115 
116 
117 // static
is_class(Type * type)118 bool ZoneTypeConfig::is_class(Type* type) {
119   return false;
120 }
121 
122 
123 // static
as_bitset(Type * type)124 ZoneTypeConfig::Type::bitset ZoneTypeConfig::as_bitset(Type* type) {
125   DCHECK(is_bitset(type));
126   return static_cast<Type::bitset>(reinterpret_cast<uintptr_t>(type) ^ 1u);
127 }
128 
129 
130 // static
as_struct(Type * type)131 ZoneTypeConfig::Struct* ZoneTypeConfig::as_struct(Type* type) {
132   DCHECK(!is_bitset(type));
133   return reinterpret_cast<Struct*>(type);
134 }
135 
136 
137 // static
as_range(Type * type)138 ZoneTypeConfig::Range* ZoneTypeConfig::as_range(Type* type) {
139   DCHECK(!is_bitset(type));
140   return reinterpret_cast<Range*>(type);
141 }
142 
143 
144 // static
as_class(Type * type)145 i::Handle<i::Map> ZoneTypeConfig::as_class(Type* type) {
146   UNREACHABLE();
147   return i::Handle<i::Map>();
148 }
149 
150 
151 // static
from_bitset(Type::bitset bitset)152 ZoneTypeConfig::Type* ZoneTypeConfig::from_bitset(Type::bitset bitset) {
153   return reinterpret_cast<Type*>(static_cast<uintptr_t>(bitset | 1u));
154 }
155 
156 
157 // static
from_bitset(Type::bitset bitset,Zone * Zone)158 ZoneTypeConfig::Type* ZoneTypeConfig::from_bitset(
159     Type::bitset bitset, Zone* Zone) {
160   return from_bitset(bitset);
161 }
162 
163 
164 // static
from_struct(Struct * structure)165 ZoneTypeConfig::Type* ZoneTypeConfig::from_struct(Struct* structure) {
166   return reinterpret_cast<Type*>(structure);
167 }
168 
169 
170 // static
from_range(Range * range)171 ZoneTypeConfig::Type* ZoneTypeConfig::from_range(Range* range) {
172   return reinterpret_cast<Type*>(range);
173 }
174 
175 
176 // static
from_class(i::Handle<i::Map> map,Zone * zone)177 ZoneTypeConfig::Type* ZoneTypeConfig::from_class(
178     i::Handle<i::Map> map, Zone* zone) {
179   return from_bitset(0);
180 }
181 
182 
183 // static
struct_create(int tag,int length,Zone * zone)184 ZoneTypeConfig::Struct* ZoneTypeConfig::struct_create(
185     int tag, int length, Zone* zone) {
186   DCHECK(tag != kRangeStructTag);
187   Struct* structure = reinterpret_cast<Struct*>(
188       zone->New(sizeof(void*) * (length + 2)));  // NOLINT
189   structure[0] = reinterpret_cast<void*>(tag);
190   structure[1] = reinterpret_cast<void*>(length);
191   return structure;
192 }
193 
194 
195 // static
struct_shrink(Struct * structure,int length)196 void ZoneTypeConfig::struct_shrink(Struct* structure, int length) {
197   DCHECK(0 <= length && length <= struct_length(structure));
198   structure[1] = reinterpret_cast<void*>(length);
199 }
200 
201 
202 // static
struct_tag(Struct * structure)203 int ZoneTypeConfig::struct_tag(Struct* structure) {
204   return static_cast<int>(reinterpret_cast<intptr_t>(structure[0]));
205 }
206 
207 
208 // static
struct_length(Struct * structure)209 int ZoneTypeConfig::struct_length(Struct* structure) {
210   return static_cast<int>(reinterpret_cast<intptr_t>(structure[1]));
211 }
212 
213 
214 // static
struct_get(Struct * structure,int i)215 Type* ZoneTypeConfig::struct_get(Struct* structure, int i) {
216   DCHECK(0 <= i && i <= struct_length(structure));
217   return static_cast<Type*>(structure[2 + i]);
218 }
219 
220 
221 // static
struct_set(Struct * structure,int i,Type * x)222 void ZoneTypeConfig::struct_set(Struct* structure, int i, Type* x) {
223   DCHECK(0 <= i && i <= struct_length(structure));
224   structure[2 + i] = x;
225 }
226 
227 
228 // static
229 template<class V>
struct_get_value(Struct * structure,int i)230 i::Handle<V> ZoneTypeConfig::struct_get_value(Struct* structure, int i) {
231   DCHECK(0 <= i && i <= struct_length(structure));
232   return i::Handle<V>(static_cast<V**>(structure[2 + i]));
233 }
234 
235 
236 // static
237 template<class V>
struct_set_value(Struct * structure,int i,i::Handle<V> x)238 void ZoneTypeConfig::struct_set_value(
239     Struct* structure, int i, i::Handle<V> x) {
240   DCHECK(0 <= i && i <= struct_length(structure));
241   structure[2 + i] = x.location();
242 }
243 
244 
245 // static
range_create(Zone * zone)246 ZoneTypeConfig::Range* ZoneTypeConfig::range_create(Zone* zone) {
247   Range* range = reinterpret_cast<Range*>(zone->New(sizeof(Range)));  // NOLINT
248   range->tag = reinterpret_cast<void*>(kRangeStructTag);
249   range->bitset = 0;
250   range->limits[0] = 1;
251   range->limits[1] = 0;
252   return range;
253 }
254 
255 
256 // static
range_get_bitset(ZoneTypeConfig::Range * range)257 int ZoneTypeConfig::range_get_bitset(ZoneTypeConfig::Range* range) {
258   return range->bitset;
259 }
260 
261 
262 // static
range_set_bitset(ZoneTypeConfig::Range * range,int value)263 void ZoneTypeConfig::range_set_bitset(ZoneTypeConfig::Range* range, int value) {
264   range->bitset = value;
265 }
266 
267 
268 // static
range_get_double(ZoneTypeConfig::Range * range,int index)269 double ZoneTypeConfig::range_get_double(ZoneTypeConfig::Range* range,
270                                         int index) {
271   DCHECK(index >= 0 && index < 2);
272   return range->limits[index];
273 }
274 
275 
276 // static
range_set_double(ZoneTypeConfig::Range * range,int index,double value,Zone *)277 void ZoneTypeConfig::range_set_double(ZoneTypeConfig::Range* range, int index,
278                                       double value, Zone*) {
279   DCHECK(index >= 0 && index < 2);
280   range->limits[index] = value;
281 }
282 
283 
284 // -----------------------------------------------------------------------------
285 // HeapTypeConfig
286 
287 // static
288 template<class T>
handle(T * type)289 i::Handle<T> HeapTypeConfig::handle(T* type) {
290   return i::handle(type, i::HeapObject::cast(type)->GetIsolate());
291 }
292 
293 
294 // static
295 template<class T>
cast(i::Handle<Type> type)296 i::Handle<T> HeapTypeConfig::cast(i::Handle<Type> type) {
297   return i::Handle<T>::cast(type);
298 }
299 
300 
301 // static
is_bitset(Type * type)302 bool HeapTypeConfig::is_bitset(Type* type) {
303   return type->IsSmi();
304 }
305 
306 
307 // static
is_class(Type * type)308 bool HeapTypeConfig::is_class(Type* type) {
309   return type->IsMap();
310 }
311 
312 
313 // static
is_struct(Type * type,int tag)314 bool HeapTypeConfig::is_struct(Type* type, int tag) {
315   DCHECK(tag != kRangeStructTag);
316   return type->IsFixedArray() && struct_tag(as_struct(type)) == tag;
317 }
318 
319 
320 // static
is_range(Type * type)321 bool HeapTypeConfig::is_range(Type* type) {
322   return type->IsFixedArray() && struct_tag(as_struct(type)) == kRangeStructTag;
323 }
324 
325 
326 // static
as_bitset(Type * type)327 HeapTypeConfig::Type::bitset HeapTypeConfig::as_bitset(Type* type) {
328   // TODO(rossberg): Breaks the Smi abstraction. Fix once there is a better way.
329   return static_cast<Type::bitset>(reinterpret_cast<uintptr_t>(type));
330 }
331 
332 
333 // static
as_class(Type * type)334 i::Handle<i::Map> HeapTypeConfig::as_class(Type* type) {
335   return i::handle(i::Map::cast(type));
336 }
337 
338 
339 // static
as_struct(Type * type)340 i::Handle<HeapTypeConfig::Struct> HeapTypeConfig::as_struct(Type* type) {
341   return i::handle(Struct::cast(type));
342 }
343 
344 
345 // static
as_range(Type * type)346 i::Handle<HeapTypeConfig::Range> HeapTypeConfig::as_range(Type* type) {
347   return i::handle(Range::cast(type));
348 }
349 
350 
351 // static
from_bitset(Type::bitset bitset)352 HeapTypeConfig::Type* HeapTypeConfig::from_bitset(Type::bitset bitset) {
353   // TODO(rossberg): Breaks the Smi abstraction. Fix once there is a better way.
354   return reinterpret_cast<Type*>(static_cast<uintptr_t>(bitset));
355 }
356 
357 
358 // static
from_bitset(Type::bitset bitset,Isolate * isolate)359 i::Handle<HeapTypeConfig::Type> HeapTypeConfig::from_bitset(
360     Type::bitset bitset, Isolate* isolate) {
361   return i::handle(from_bitset(bitset), isolate);
362 }
363 
364 
365 // static
from_class(i::Handle<i::Map> map,Isolate * isolate)366 i::Handle<HeapTypeConfig::Type> HeapTypeConfig::from_class(
367     i::Handle<i::Map> map, Isolate* isolate) {
368   return i::Handle<Type>::cast(i::Handle<Object>::cast(map));
369 }
370 
371 
372 // static
from_struct(i::Handle<Struct> structure)373 i::Handle<HeapTypeConfig::Type> HeapTypeConfig::from_struct(
374     i::Handle<Struct> structure) {
375   return i::Handle<Type>::cast(i::Handle<Object>::cast(structure));
376 }
377 
378 
379 // static
from_range(i::Handle<Range> range)380 i::Handle<HeapTypeConfig::Type> HeapTypeConfig::from_range(
381     i::Handle<Range> range) {
382   return i::Handle<Type>::cast(i::Handle<Object>::cast(range));
383 }
384 
385 
386 // static
struct_create(int tag,int length,Isolate * isolate)387 i::Handle<HeapTypeConfig::Struct> HeapTypeConfig::struct_create(
388     int tag, int length, Isolate* isolate) {
389   i::Handle<Struct> structure = isolate->factory()->NewFixedArray(length + 1);
390   structure->set(0, i::Smi::FromInt(tag));
391   return structure;
392 }
393 
394 
395 // static
struct_shrink(i::Handle<Struct> structure,int length)396 void HeapTypeConfig::struct_shrink(i::Handle<Struct> structure, int length) {
397   structure->Shrink(length + 1);
398 }
399 
400 
401 // static
struct_tag(i::Handle<Struct> structure)402 int HeapTypeConfig::struct_tag(i::Handle<Struct> structure) {
403   return static_cast<i::Smi*>(structure->get(0))->value();
404 }
405 
406 
407 // static
struct_length(i::Handle<Struct> structure)408 int HeapTypeConfig::struct_length(i::Handle<Struct> structure) {
409   return structure->length() - 1;
410 }
411 
412 
413 // static
struct_get(i::Handle<Struct> structure,int i)414 i::Handle<HeapTypeConfig::Type> HeapTypeConfig::struct_get(
415     i::Handle<Struct> structure, int i) {
416   Type* type = static_cast<Type*>(structure->get(i + 1));
417   return i::handle(type, structure->GetIsolate());
418 }
419 
420 
421 // static
struct_set(i::Handle<Struct> structure,int i,i::Handle<Type> type)422 void HeapTypeConfig::struct_set(
423     i::Handle<Struct> structure, int i, i::Handle<Type> type) {
424   structure->set(i + 1, *type);
425 }
426 
427 
428 // static
429 template<class V>
struct_get_value(i::Handle<Struct> structure,int i)430 i::Handle<V> HeapTypeConfig::struct_get_value(
431     i::Handle<Struct> structure, int i) {
432   V* x = static_cast<V*>(structure->get(i + 1));
433   return i::handle(x, structure->GetIsolate());
434 }
435 
436 
437 // static
438 template<class V>
struct_set_value(i::Handle<Struct> structure,int i,i::Handle<V> x)439 void HeapTypeConfig::struct_set_value(
440     i::Handle<Struct> structure, int i, i::Handle<V> x) {
441   structure->set(i + 1, *x);
442 }
443 
444 
445 // static
range_create(Isolate * isolate)446 i::Handle<HeapTypeConfig::Range> HeapTypeConfig::range_create(
447     Isolate* isolate) {
448   i::Handle<Range> range = isolate->factory()->NewFixedArray(4);
449   range->set(0, i::Smi::FromInt(kRangeStructTag));
450   return range;
451 }
452 
453 
454 // static
range_get_bitset(i::Handle<HeapTypeConfig::Range> range)455 int HeapTypeConfig::range_get_bitset(i::Handle<HeapTypeConfig::Range> range) {
456   Type* v = static_cast<Type*>(range->get(1));
457   return as_bitset(v);
458 }
459 
460 
461 // static
range_set_bitset(i::Handle<HeapTypeConfig::Range> range,int value)462 void HeapTypeConfig::range_set_bitset(i::Handle<HeapTypeConfig::Range> range,
463                                       int value) {
464   range->set(1, from_bitset(value));
465 }
466 
467 
468 // static
range_get_double(i::Handle<HeapTypeConfig::Range> range,int index)469 double HeapTypeConfig::range_get_double(i::Handle<HeapTypeConfig::Range> range,
470                                         int index) {
471   DCHECK(index >= 0 && index < 2);
472   return range->get(index + 2)->Number();
473 }
474 
475 
476 // static
range_set_double(i::Handle<HeapTypeConfig::Range> range,int index,double value,Isolate * isolate)477 void HeapTypeConfig::range_set_double(i::Handle<HeapTypeConfig::Range> range,
478                                       int index, double value,
479                                       Isolate* isolate) {
480   DCHECK(index >= 0 && index < 2);
481   i::Handle<Object> number = isolate->factory()->NewNumber(value);
482   range->set(index + 2, *number);
483 }
484 }  // namespace internal
485 }  // namespace v8
486 
487 #endif  // V8_TYPES_INL_H_
488