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 #include "src/compiler/access-builder.h"
6 
7 #include "src/contexts.h"
8 #include "src/frames.h"
9 #include "src/heap/heap.h"
10 #include "src/type-cache.h"
11 #include "src/types-inl.h"
12 
13 namespace v8 {
14 namespace internal {
15 namespace compiler {
16 
17 // static
ForMap()18 FieldAccess AccessBuilder::ForMap() {
19   FieldAccess access = {kTaggedBase, HeapObject::kMapOffset,
20                         MaybeHandle<Name>(), Type::Any(),
21                         MachineType::AnyTagged()};
22   return access;
23 }
24 
25 
26 // static
ForHeapNumberValue()27 FieldAccess AccessBuilder::ForHeapNumberValue() {
28   FieldAccess access = {kTaggedBase, HeapNumber::kValueOffset,
29                         MaybeHandle<Name>(), TypeCache().Get().kFloat64,
30                         MachineType::Float64()};
31   return access;
32 }
33 
34 
35 // static
ForJSObjectProperties()36 FieldAccess AccessBuilder::ForJSObjectProperties() {
37   FieldAccess access = {kTaggedBase, JSObject::kPropertiesOffset,
38                         MaybeHandle<Name>(), Type::Internal(),
39                         MachineType::AnyTagged()};
40   return access;
41 }
42 
43 
44 // static
ForJSObjectElements()45 FieldAccess AccessBuilder::ForJSObjectElements() {
46   FieldAccess access = {kTaggedBase, JSObject::kElementsOffset,
47                         MaybeHandle<Name>(), Type::Internal(),
48                         MachineType::AnyTagged()};
49   return access;
50 }
51 
52 
53 // static
ForJSObjectInObjectProperty(Handle<Map> map,int index)54 FieldAccess AccessBuilder::ForJSObjectInObjectProperty(Handle<Map> map,
55                                                        int index) {
56   int const offset = map->GetInObjectPropertyOffset(index);
57   FieldAccess access = {kTaggedBase, offset, MaybeHandle<Name>(),
58                         Type::Tagged(), MachineType::AnyTagged()};
59   return access;
60 }
61 
62 
63 // static
ForJSFunctionContext()64 FieldAccess AccessBuilder::ForJSFunctionContext() {
65   FieldAccess access = {kTaggedBase, JSFunction::kContextOffset,
66                         MaybeHandle<Name>(), Type::Internal(),
67                         MachineType::AnyTagged()};
68   return access;
69 }
70 
71 
72 // static
ForJSFunctionSharedFunctionInfo()73 FieldAccess AccessBuilder::ForJSFunctionSharedFunctionInfo() {
74   FieldAccess access = {kTaggedBase, JSFunction::kSharedFunctionInfoOffset,
75                         Handle<Name>(), Type::Any(), MachineType::AnyTagged()};
76   return access;
77 }
78 
79 
80 // static
ForJSArrayLength(ElementsKind elements_kind)81 FieldAccess AccessBuilder::ForJSArrayLength(ElementsKind elements_kind) {
82   TypeCache const& type_cache = TypeCache::Get();
83   FieldAccess access = {kTaggedBase, JSArray::kLengthOffset, Handle<Name>(),
84                         type_cache.kJSArrayLengthType,
85                         MachineType::AnyTagged()};
86   if (IsFastDoubleElementsKind(elements_kind)) {
87     access.type = type_cache.kFixedDoubleArrayLengthType;
88   } else if (IsFastElementsKind(elements_kind)) {
89     access.type = type_cache.kFixedArrayLengthType;
90   }
91   return access;
92 }
93 
94 
95 // static
ForJSArrayBufferBackingStore()96 FieldAccess AccessBuilder::ForJSArrayBufferBackingStore() {
97   FieldAccess access = {kTaggedBase, JSArrayBuffer::kBackingStoreOffset,
98                         MaybeHandle<Name>(), Type::UntaggedPointer(),
99                         MachineType::Pointer()};
100   return access;
101 }
102 
103 
104 // static
ForJSArrayBufferBitField()105 FieldAccess AccessBuilder::ForJSArrayBufferBitField() {
106   FieldAccess access = {kTaggedBase, JSArrayBuffer::kBitFieldOffset,
107                         MaybeHandle<Name>(), TypeCache::Get().kInt8,
108                         MachineType::Int8()};
109   return access;
110 }
111 
112 
113 // static
ForJSArrayBufferViewBuffer()114 FieldAccess AccessBuilder::ForJSArrayBufferViewBuffer() {
115   FieldAccess access = {kTaggedBase, JSArrayBufferView::kBufferOffset,
116                         MaybeHandle<Name>(), Type::TaggedPointer(),
117                         MachineType::AnyTagged()};
118   return access;
119 }
120 
121 
122 // static
ForJSDateField(JSDate::FieldIndex index)123 FieldAccess AccessBuilder::ForJSDateField(JSDate::FieldIndex index) {
124   FieldAccess access = {
125       kTaggedBase, JSDate::kValueOffset + index * kPointerSize,
126       MaybeHandle<Name>(), Type::Number(), MachineType::AnyTagged()};
127   return access;
128 }
129 
130 
131 // static
ForJSIteratorResultDone()132 FieldAccess AccessBuilder::ForJSIteratorResultDone() {
133   FieldAccess access = {kTaggedBase, JSIteratorResult::kDoneOffset,
134                         MaybeHandle<Name>(), Type::Any(),
135                         MachineType::AnyTagged()};
136   return access;
137 }
138 
139 
140 // static
ForJSIteratorResultValue()141 FieldAccess AccessBuilder::ForJSIteratorResultValue() {
142   FieldAccess access = {kTaggedBase, JSIteratorResult::kValueOffset,
143                         MaybeHandle<Name>(), Type::Any(),
144                         MachineType::AnyTagged()};
145   return access;
146 }
147 
148 
149 // static
ForJSRegExpFlags()150 FieldAccess AccessBuilder::ForJSRegExpFlags() {
151   FieldAccess access = {kTaggedBase, JSRegExp::kFlagsOffset,
152                         MaybeHandle<Name>(), Type::Tagged(),
153                         MachineType::AnyTagged()};
154   return access;
155 }
156 
157 
158 // static
ForJSRegExpSource()159 FieldAccess AccessBuilder::ForJSRegExpSource() {
160   FieldAccess access = {kTaggedBase, JSRegExp::kSourceOffset,
161                         MaybeHandle<Name>(), Type::Tagged(),
162                         MachineType::AnyTagged()};
163   return access;
164 }
165 
166 
167 // static
ForFixedArrayLength()168 FieldAccess AccessBuilder::ForFixedArrayLength() {
169   FieldAccess access = {
170       kTaggedBase, FixedArray::kLengthOffset, MaybeHandle<Name>(),
171       TypeCache::Get().kFixedArrayLengthType, MachineType::AnyTagged()};
172   return access;
173 }
174 
175 
176 // static
ForDescriptorArrayEnumCache()177 FieldAccess AccessBuilder::ForDescriptorArrayEnumCache() {
178   FieldAccess access = {kTaggedBase, DescriptorArray::kEnumCacheOffset,
179                         Handle<Name>(), Type::TaggedPointer(),
180                         MachineType::AnyTagged()};
181   return access;
182 }
183 
184 
185 // static
ForDescriptorArrayEnumCacheBridgeCache()186 FieldAccess AccessBuilder::ForDescriptorArrayEnumCacheBridgeCache() {
187   FieldAccess access = {
188       kTaggedBase, DescriptorArray::kEnumCacheBridgeCacheOffset, Handle<Name>(),
189       Type::TaggedPointer(), MachineType::AnyTagged()};
190   return access;
191 }
192 
193 
194 // static
ForMapBitField()195 FieldAccess AccessBuilder::ForMapBitField() {
196   FieldAccess access = {kTaggedBase, Map::kBitFieldOffset, Handle<Name>(),
197                         TypeCache::Get().kUint8, MachineType::Uint8()};
198   return access;
199 }
200 
201 
202 // static
ForMapBitField3()203 FieldAccess AccessBuilder::ForMapBitField3() {
204   FieldAccess access = {kTaggedBase, Map::kBitField3Offset, Handle<Name>(),
205                         TypeCache::Get().kInt32, MachineType::Int32()};
206   return access;
207 }
208 
209 
210 // static
ForMapDescriptors()211 FieldAccess AccessBuilder::ForMapDescriptors() {
212   FieldAccess access = {kTaggedBase, Map::kDescriptorsOffset, Handle<Name>(),
213                         Type::TaggedPointer(), MachineType::AnyTagged()};
214   return access;
215 }
216 
217 
218 // static
ForMapInstanceType()219 FieldAccess AccessBuilder::ForMapInstanceType() {
220   FieldAccess access = {kTaggedBase, Map::kInstanceTypeOffset, Handle<Name>(),
221                         TypeCache::Get().kUint8, MachineType::Uint8()};
222   return access;
223 }
224 
225 
226 // static
ForMapPrototype()227 FieldAccess AccessBuilder::ForMapPrototype() {
228   FieldAccess access = {kTaggedBase, Map::kPrototypeOffset, Handle<Name>(),
229                         Type::TaggedPointer(), MachineType::AnyTagged()};
230   return access;
231 }
232 
233 
234 // static
ForStringLength()235 FieldAccess AccessBuilder::ForStringLength() {
236   FieldAccess access = {kTaggedBase, String::kLengthOffset, Handle<Name>(),
237                         TypeCache::Get().kStringLengthType,
238                         MachineType::AnyTagged()};
239   return access;
240 }
241 
242 
243 // static
ForJSGlobalObjectGlobalProxy()244 FieldAccess AccessBuilder::ForJSGlobalObjectGlobalProxy() {
245   FieldAccess access = {kTaggedBase, JSGlobalObject::kGlobalProxyOffset,
246                         Handle<Name>(), Type::Receiver(),
247                         MachineType::AnyTagged()};
248   return access;
249 }
250 
251 
252 // static
ForJSGlobalObjectNativeContext()253 FieldAccess AccessBuilder::ForJSGlobalObjectNativeContext() {
254   FieldAccess access = {kTaggedBase, JSGlobalObject::kNativeContextOffset,
255                         Handle<Name>(), Type::Internal(),
256                         MachineType::AnyTagged()};
257   return access;
258 }
259 
260 
261 // static
ForValue()262 FieldAccess AccessBuilder::ForValue() {
263   FieldAccess access = {kTaggedBase, JSValue::kValueOffset, Handle<Name>(),
264                         Type::Any(), MachineType::AnyTagged()};
265   return access;
266 }
267 
268 
269 // static
ForArgumentsLength()270 FieldAccess AccessBuilder::ForArgumentsLength() {
271   int offset =
272       JSObject::kHeaderSize + Heap::kArgumentsLengthIndex * kPointerSize;
273   FieldAccess access = {kTaggedBase, offset, Handle<Name>(), Type::Any(),
274                         MachineType::AnyTagged()};
275   return access;
276 }
277 
278 
279 // static
ForArgumentsCallee()280 FieldAccess AccessBuilder::ForArgumentsCallee() {
281   int offset =
282       JSObject::kHeaderSize + Heap::kArgumentsCalleeIndex * kPointerSize;
283   FieldAccess access = {kTaggedBase, offset, Handle<Name>(), Type::Any(),
284                         MachineType::AnyTagged()};
285   return access;
286 }
287 
288 
289 // static
ForFixedArraySlot(size_t index)290 FieldAccess AccessBuilder::ForFixedArraySlot(size_t index) {
291   int offset = FixedArray::OffsetOfElementAt(static_cast<int>(index));
292   FieldAccess access = {kTaggedBase, offset, Handle<Name>(), Type::Any(),
293                         MachineType::AnyTagged()};
294   return access;
295 }
296 
297 
298 // static
ForContextSlot(size_t index)299 FieldAccess AccessBuilder::ForContextSlot(size_t index) {
300   int offset = Context::kHeaderSize + static_cast<int>(index) * kPointerSize;
301   DCHECK_EQ(offset,
302             Context::SlotOffset(static_cast<int>(index)) + kHeapObjectTag);
303   FieldAccess access = {kTaggedBase, offset, Handle<Name>(), Type::Any(),
304                         MachineType::AnyTagged()};
305   return access;
306 }
307 
308 
309 // static
ForPropertyCellValue()310 FieldAccess AccessBuilder::ForPropertyCellValue() {
311   return ForPropertyCellValue(Type::Tagged());
312 }
313 
314 
315 // static
ForPropertyCellValue(Type * type)316 FieldAccess AccessBuilder::ForPropertyCellValue(Type* type) {
317   FieldAccess access = {kTaggedBase, PropertyCell::kValueOffset, Handle<Name>(),
318                         type, MachineType::AnyTagged()};
319   return access;
320 }
321 
322 
323 // static
ForSharedFunctionInfoTypeFeedbackVector()324 FieldAccess AccessBuilder::ForSharedFunctionInfoTypeFeedbackVector() {
325   FieldAccess access = {kTaggedBase, SharedFunctionInfo::kFeedbackVectorOffset,
326                         Handle<Name>(), Type::Any(), MachineType::AnyTagged()};
327   return access;
328 }
329 
330 
331 // static
ForFixedArrayElement()332 ElementAccess AccessBuilder::ForFixedArrayElement() {
333   ElementAccess access = {kTaggedBase, FixedArray::kHeaderSize, Type::Tagged(),
334                           MachineType::AnyTagged()};
335   return access;
336 }
337 
338 
339 // static
ForFixedDoubleArrayElement()340 ElementAccess AccessBuilder::ForFixedDoubleArrayElement() {
341   ElementAccess access = {kTaggedBase, FixedDoubleArray::kHeaderSize,
342                           TypeCache::Get().kFloat64, MachineType::Float64()};
343   return access;
344 }
345 
346 
347 // static
ForTypedArrayElement(ExternalArrayType type,bool is_external)348 ElementAccess AccessBuilder::ForTypedArrayElement(ExternalArrayType type,
349                                                   bool is_external) {
350   BaseTaggedness taggedness = is_external ? kUntaggedBase : kTaggedBase;
351   int header_size = is_external ? 0 : FixedTypedArrayBase::kDataOffset;
352   switch (type) {
353     case kExternalInt8Array: {
354       ElementAccess access = {taggedness, header_size, Type::Signed32(),
355                               MachineType::Int8()};
356       return access;
357     }
358     case kExternalUint8Array:
359     case kExternalUint8ClampedArray: {
360       ElementAccess access = {taggedness, header_size, Type::Unsigned32(),
361                               MachineType::Uint8()};
362       return access;
363     }
364     case kExternalInt16Array: {
365       ElementAccess access = {taggedness, header_size, Type::Signed32(),
366                               MachineType::Int16()};
367       return access;
368     }
369     case kExternalUint16Array: {
370       ElementAccess access = {taggedness, header_size, Type::Unsigned32(),
371                               MachineType::Uint16()};
372       return access;
373     }
374     case kExternalInt32Array: {
375       ElementAccess access = {taggedness, header_size, Type::Signed32(),
376                               MachineType::Int32()};
377       return access;
378     }
379     case kExternalUint32Array: {
380       ElementAccess access = {taggedness, header_size, Type::Unsigned32(),
381                               MachineType::Uint32()};
382       return access;
383     }
384     case kExternalFloat32Array: {
385       ElementAccess access = {taggedness, header_size, Type::Number(),
386                               MachineType::Float32()};
387       return access;
388     }
389     case kExternalFloat64Array: {
390       ElementAccess access = {taggedness, header_size, Type::Number(),
391                               MachineType::Float64()};
392       return access;
393     }
394   }
395   UNREACHABLE();
396   ElementAccess access = {kUntaggedBase, 0, Type::None(), MachineType::None()};
397   return access;
398 }
399 
400 
401 // static
ForStatsCounter()402 FieldAccess AccessBuilder::ForStatsCounter() {
403   FieldAccess access = {kUntaggedBase, 0, MaybeHandle<Name>(),
404                         TypeCache::Get().kInt32, MachineType::Int32()};
405   return access;
406 }
407 
408 }  // namespace compiler
409 }  // namespace internal
410 }  // namespace v8
411