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/handles-inl.h"
10 #include "src/heap/heap.h"
11 #include "src/type-cache.h"
12
13 namespace v8 {
14 namespace internal {
15 namespace compiler {
16
17 // static
ForMap()18 FieldAccess AccessBuilder::ForMap() {
19 FieldAccess access = {
20 kTaggedBase, HeapObject::kMapOffset, MaybeHandle<Name>(),
21 Type::Any(), MachineType::AnyTagged(), kMapWriteBarrier};
22 return access;
23 }
24
25
26 // static
ForHeapNumberValue()27 FieldAccess AccessBuilder::ForHeapNumberValue() {
28 FieldAccess access = {kTaggedBase,
29 HeapNumber::kValueOffset,
30 MaybeHandle<Name>(),
31 TypeCache::Get().kFloat64,
32 MachineType::Float64(),
33 kNoWriteBarrier};
34 return access;
35 }
36
37
38 // static
ForJSObjectProperties()39 FieldAccess AccessBuilder::ForJSObjectProperties() {
40 FieldAccess access = {
41 kTaggedBase, JSObject::kPropertiesOffset, MaybeHandle<Name>(),
42 Type::Internal(), MachineType::AnyTagged(), kPointerWriteBarrier};
43 return access;
44 }
45
46
47 // static
ForJSObjectElements()48 FieldAccess AccessBuilder::ForJSObjectElements() {
49 FieldAccess access = {
50 kTaggedBase, JSObject::kElementsOffset, MaybeHandle<Name>(),
51 Type::Internal(), MachineType::AnyTagged(), kPointerWriteBarrier};
52 return access;
53 }
54
55
56 // static
ForJSObjectInObjectProperty(Handle<Map> map,int index)57 FieldAccess AccessBuilder::ForJSObjectInObjectProperty(Handle<Map> map,
58 int index) {
59 int const offset = map->GetInObjectPropertyOffset(index);
60 FieldAccess access = {kTaggedBase,
61 offset,
62 MaybeHandle<Name>(),
63 Type::Tagged(),
64 MachineType::AnyTagged(),
65 kFullWriteBarrier};
66 return access;
67 }
68
69
70 // static
ForJSFunctionPrototypeOrInitialMap()71 FieldAccess AccessBuilder::ForJSFunctionPrototypeOrInitialMap() {
72 FieldAccess access = {kTaggedBase,
73 JSFunction::kPrototypeOrInitialMapOffset,
74 MaybeHandle<Name>(),
75 Type::Any(),
76 MachineType::AnyTagged(),
77 kFullWriteBarrier};
78 return access;
79 }
80
81 // static
ForJSFunctionContext()82 FieldAccess AccessBuilder::ForJSFunctionContext() {
83 FieldAccess access = {
84 kTaggedBase, JSFunction::kContextOffset, MaybeHandle<Name>(),
85 Type::Internal(), MachineType::AnyTagged(), kPointerWriteBarrier};
86 return access;
87 }
88
89
90 // static
ForJSFunctionSharedFunctionInfo()91 FieldAccess AccessBuilder::ForJSFunctionSharedFunctionInfo() {
92 FieldAccess access = {kTaggedBase,
93 JSFunction::kSharedFunctionInfoOffset,
94 Handle<Name>(),
95 Type::Any(),
96 MachineType::AnyTagged(),
97 kPointerWriteBarrier};
98 return access;
99 }
100
101 // static
ForJSFunctionLiterals()102 FieldAccess AccessBuilder::ForJSFunctionLiterals() {
103 FieldAccess access = {
104 kTaggedBase, JSFunction::kLiteralsOffset, Handle<Name>(),
105 Type::Internal(), MachineType::AnyTagged(), kPointerWriteBarrier};
106 return access;
107 }
108
109 // static
ForJSFunctionCodeEntry()110 FieldAccess AccessBuilder::ForJSFunctionCodeEntry() {
111 FieldAccess access = {kTaggedBase,
112 JSFunction::kCodeEntryOffset,
113 Handle<Name>(),
114 Type::UntaggedPointer(),
115 MachineType::Pointer(),
116 kNoWriteBarrier};
117 return access;
118 }
119
120 // static
ForJSFunctionNextFunctionLink()121 FieldAccess AccessBuilder::ForJSFunctionNextFunctionLink() {
122 FieldAccess access = {kTaggedBase,
123 JSFunction::kNextFunctionLinkOffset,
124 Handle<Name>(),
125 Type::Any(),
126 MachineType::AnyTagged(),
127 kPointerWriteBarrier};
128 return access;
129 }
130
131 // static
ForJSGeneratorObjectContext()132 FieldAccess AccessBuilder::ForJSGeneratorObjectContext() {
133 FieldAccess access = {kTaggedBase,
134 JSGeneratorObject::kContextOffset,
135 Handle<Name>(),
136 Type::Internal(),
137 MachineType::AnyTagged(),
138 kPointerWriteBarrier};
139 return access;
140 }
141
142 // static
ForJSGeneratorObjectContinuation()143 FieldAccess AccessBuilder::ForJSGeneratorObjectContinuation() {
144 TypeCache const& type_cache = TypeCache::Get();
145 FieldAccess access = {kTaggedBase,
146 JSGeneratorObject::kContinuationOffset,
147 Handle<Name>(),
148 type_cache.kSmi,
149 MachineType::AnyTagged(),
150 kNoWriteBarrier};
151 return access;
152 }
153
154 // static
ForJSGeneratorObjectInputOrDebugPos()155 FieldAccess AccessBuilder::ForJSGeneratorObjectInputOrDebugPos() {
156 FieldAccess access = {kTaggedBase,
157 JSGeneratorObject::kInputOrDebugPosOffset,
158 Handle<Name>(),
159 Type::Any(),
160 MachineType::AnyTagged(),
161 kFullWriteBarrier};
162 return access;
163 }
164
165 // static
ForJSGeneratorObjectOperandStack()166 FieldAccess AccessBuilder::ForJSGeneratorObjectOperandStack() {
167 FieldAccess access = {kTaggedBase,
168 JSGeneratorObject::kOperandStackOffset,
169 Handle<Name>(),
170 Type::Internal(),
171 MachineType::AnyTagged(),
172 kPointerWriteBarrier};
173 return access;
174 }
175
176 // static
ForJSGeneratorObjectResumeMode()177 FieldAccess AccessBuilder::ForJSGeneratorObjectResumeMode() {
178 TypeCache const& type_cache = TypeCache::Get();
179 FieldAccess access = {kTaggedBase,
180 JSGeneratorObject::kResumeModeOffset,
181 Handle<Name>(),
182 type_cache.kSmi,
183 MachineType::AnyTagged(),
184 kNoWriteBarrier};
185 return access;
186 }
187
188 // static
ForJSArrayLength(ElementsKind elements_kind)189 FieldAccess AccessBuilder::ForJSArrayLength(ElementsKind elements_kind) {
190 TypeCache const& type_cache = TypeCache::Get();
191 FieldAccess access = {kTaggedBase,
192 JSArray::kLengthOffset,
193 Handle<Name>(),
194 type_cache.kJSArrayLengthType,
195 MachineType::AnyTagged(),
196 kFullWriteBarrier};
197 if (IsFastDoubleElementsKind(elements_kind)) {
198 access.type = type_cache.kFixedDoubleArrayLengthType;
199 access.write_barrier_kind = kNoWriteBarrier;
200 } else if (IsFastElementsKind(elements_kind)) {
201 access.type = type_cache.kFixedArrayLengthType;
202 access.write_barrier_kind = kNoWriteBarrier;
203 }
204 return access;
205 }
206
207
208 // static
ForJSArrayBufferBackingStore()209 FieldAccess AccessBuilder::ForJSArrayBufferBackingStore() {
210 FieldAccess access = {kTaggedBase,
211 JSArrayBuffer::kBackingStoreOffset,
212 MaybeHandle<Name>(),
213 Type::UntaggedPointer(),
214 MachineType::Pointer(),
215 kNoWriteBarrier};
216 return access;
217 }
218
219
220 // static
ForJSArrayBufferBitField()221 FieldAccess AccessBuilder::ForJSArrayBufferBitField() {
222 FieldAccess access = {kTaggedBase, JSArrayBuffer::kBitFieldOffset,
223 MaybeHandle<Name>(), TypeCache::Get().kInt8,
224 MachineType::Int8(), kNoWriteBarrier};
225 return access;
226 }
227
228
229 // static
ForJSArrayBufferViewBuffer()230 FieldAccess AccessBuilder::ForJSArrayBufferViewBuffer() {
231 FieldAccess access = {kTaggedBase,
232 JSArrayBufferView::kBufferOffset,
233 MaybeHandle<Name>(),
234 Type::TaggedPointer(),
235 MachineType::AnyTagged(),
236 kPointerWriteBarrier};
237 return access;
238 }
239
240
241 // static
ForJSDateField(JSDate::FieldIndex index)242 FieldAccess AccessBuilder::ForJSDateField(JSDate::FieldIndex index) {
243 FieldAccess access = {kTaggedBase,
244 JSDate::kValueOffset + index * kPointerSize,
245 MaybeHandle<Name>(),
246 Type::Number(),
247 MachineType::AnyTagged(),
248 kFullWriteBarrier};
249 return access;
250 }
251
252
253 // static
ForJSIteratorResultDone()254 FieldAccess AccessBuilder::ForJSIteratorResultDone() {
255 FieldAccess access = {
256 kTaggedBase, JSIteratorResult::kDoneOffset, MaybeHandle<Name>(),
257 Type::Any(), MachineType::AnyTagged(), kFullWriteBarrier};
258 return access;
259 }
260
261
262 // static
ForJSIteratorResultValue()263 FieldAccess AccessBuilder::ForJSIteratorResultValue() {
264 FieldAccess access = {
265 kTaggedBase, JSIteratorResult::kValueOffset, MaybeHandle<Name>(),
266 Type::Any(), MachineType::AnyTagged(), kFullWriteBarrier};
267 return access;
268 }
269
270
271 // static
ForJSRegExpFlags()272 FieldAccess AccessBuilder::ForJSRegExpFlags() {
273 FieldAccess access = {
274 kTaggedBase, JSRegExp::kFlagsOffset, MaybeHandle<Name>(),
275 Type::Tagged(), MachineType::AnyTagged(), kFullWriteBarrier};
276 return access;
277 }
278
279
280 // static
ForJSRegExpSource()281 FieldAccess AccessBuilder::ForJSRegExpSource() {
282 FieldAccess access = {
283 kTaggedBase, JSRegExp::kSourceOffset, MaybeHandle<Name>(),
284 Type::Tagged(), MachineType::AnyTagged(), kFullWriteBarrier};
285 return access;
286 }
287
288
289 // static
ForFixedArrayLength()290 FieldAccess AccessBuilder::ForFixedArrayLength() {
291 FieldAccess access = {kTaggedBase,
292 FixedArray::kLengthOffset,
293 MaybeHandle<Name>(),
294 TypeCache::Get().kFixedArrayLengthType,
295 MachineType::AnyTagged(),
296 kNoWriteBarrier};
297 return access;
298 }
299
300
301 // static
ForDescriptorArrayEnumCache()302 FieldAccess AccessBuilder::ForDescriptorArrayEnumCache() {
303 FieldAccess access = {kTaggedBase,
304 DescriptorArray::kEnumCacheOffset,
305 Handle<Name>(),
306 Type::TaggedPointer(),
307 MachineType::AnyTagged(),
308 kPointerWriteBarrier};
309 return access;
310 }
311
312
313 // static
ForDescriptorArrayEnumCacheBridgeCache()314 FieldAccess AccessBuilder::ForDescriptorArrayEnumCacheBridgeCache() {
315 FieldAccess access = {kTaggedBase,
316 DescriptorArray::kEnumCacheBridgeCacheOffset,
317 Handle<Name>(),
318 Type::TaggedPointer(),
319 MachineType::AnyTagged(),
320 kPointerWriteBarrier};
321 return access;
322 }
323
324
325 // static
ForMapBitField()326 FieldAccess AccessBuilder::ForMapBitField() {
327 FieldAccess access = {kTaggedBase, Map::kBitFieldOffset,
328 Handle<Name>(), TypeCache::Get().kUint8,
329 MachineType::Uint8(), kNoWriteBarrier};
330 return access;
331 }
332
333
334 // static
ForMapBitField3()335 FieldAccess AccessBuilder::ForMapBitField3() {
336 FieldAccess access = {kTaggedBase, Map::kBitField3Offset,
337 Handle<Name>(), TypeCache::Get().kInt32,
338 MachineType::Int32(), kNoWriteBarrier};
339 return access;
340 }
341
342
343 // static
ForMapDescriptors()344 FieldAccess AccessBuilder::ForMapDescriptors() {
345 FieldAccess access = {
346 kTaggedBase, Map::kDescriptorsOffset, Handle<Name>(),
347 Type::TaggedPointer(), MachineType::AnyTagged(), kPointerWriteBarrier};
348 return access;
349 }
350
351
352 // static
ForMapInstanceType()353 FieldAccess AccessBuilder::ForMapInstanceType() {
354 FieldAccess access = {kTaggedBase, Map::kInstanceTypeOffset,
355 Handle<Name>(), TypeCache::Get().kUint8,
356 MachineType::Uint8(), kNoWriteBarrier};
357 return access;
358 }
359
360
361 // static
ForMapPrototype()362 FieldAccess AccessBuilder::ForMapPrototype() {
363 FieldAccess access = {
364 kTaggedBase, Map::kPrototypeOffset, Handle<Name>(),
365 Type::TaggedPointer(), MachineType::AnyTagged(), kPointerWriteBarrier};
366 return access;
367 }
368
369
370 // static
ForNameHashField()371 FieldAccess AccessBuilder::ForNameHashField() {
372 FieldAccess access = {kTaggedBase, Name::kHashFieldOffset,
373 Handle<Name>(), Type::Internal(),
374 MachineType::Uint32(), kNoWriteBarrier};
375 return access;
376 }
377
378 // static
ForStringLength()379 FieldAccess AccessBuilder::ForStringLength() {
380 FieldAccess access = {kTaggedBase,
381 String::kLengthOffset,
382 Handle<Name>(),
383 TypeCache::Get().kStringLengthType,
384 MachineType::AnyTagged(),
385 kNoWriteBarrier};
386 return access;
387 }
388
389
390 // static
ForJSGlobalObjectGlobalProxy()391 FieldAccess AccessBuilder::ForJSGlobalObjectGlobalProxy() {
392 FieldAccess access = {kTaggedBase,
393 JSGlobalObject::kGlobalProxyOffset,
394 Handle<Name>(),
395 Type::Receiver(),
396 MachineType::AnyTagged(),
397 kPointerWriteBarrier};
398 return access;
399 }
400
401
402 // static
ForJSGlobalObjectNativeContext()403 FieldAccess AccessBuilder::ForJSGlobalObjectNativeContext() {
404 FieldAccess access = {kTaggedBase,
405 JSGlobalObject::kNativeContextOffset,
406 Handle<Name>(),
407 Type::Internal(),
408 MachineType::AnyTagged(),
409 kPointerWriteBarrier};
410 return access;
411 }
412
413
414 // static
ForValue()415 FieldAccess AccessBuilder::ForValue() {
416 FieldAccess access = {
417 kTaggedBase, JSValue::kValueOffset, Handle<Name>(),
418 Type::Any(), MachineType::AnyTagged(), kFullWriteBarrier};
419 return access;
420 }
421
422
423 // static
ForArgumentsLength()424 FieldAccess AccessBuilder::ForArgumentsLength() {
425 FieldAccess access = {
426 kTaggedBase, JSArgumentsObject::kLengthOffset, Handle<Name>(),
427 Type::Any(), MachineType::AnyTagged(), kFullWriteBarrier};
428 return access;
429 }
430
431
432 // static
ForArgumentsCallee()433 FieldAccess AccessBuilder::ForArgumentsCallee() {
434 FieldAccess access = {kTaggedBase,
435 JSSloppyArgumentsObject::kCalleeOffset,
436 Handle<Name>(),
437 Type::Any(),
438 MachineType::AnyTagged(),
439 kPointerWriteBarrier};
440 return access;
441 }
442
443
444 // static
ForFixedArraySlot(size_t index)445 FieldAccess AccessBuilder::ForFixedArraySlot(size_t index) {
446 int offset = FixedArray::OffsetOfElementAt(static_cast<int>(index));
447 FieldAccess access = {kTaggedBase,
448 offset,
449 Handle<Name>(),
450 Type::Any(),
451 MachineType::AnyTagged(),
452 kFullWriteBarrier};
453 return access;
454 }
455
456
457 // static
ForContextSlot(size_t index)458 FieldAccess AccessBuilder::ForContextSlot(size_t index) {
459 int offset = Context::kHeaderSize + static_cast<int>(index) * kPointerSize;
460 DCHECK_EQ(offset,
461 Context::SlotOffset(static_cast<int>(index)) + kHeapObjectTag);
462 FieldAccess access = {kTaggedBase,
463 offset,
464 Handle<Name>(),
465 Type::Any(),
466 MachineType::AnyTagged(),
467 kFullWriteBarrier};
468 return access;
469 }
470
471
472 // static
ForPropertyCellValue()473 FieldAccess AccessBuilder::ForPropertyCellValue() {
474 return ForPropertyCellValue(Type::Tagged());
475 }
476
477
478 // static
ForPropertyCellValue(Type * type)479 FieldAccess AccessBuilder::ForPropertyCellValue(Type* type) {
480 FieldAccess access = {
481 kTaggedBase, PropertyCell::kValueOffset, Handle<Name>(),
482 type, MachineType::AnyTagged(), kFullWriteBarrier};
483 return access;
484 }
485
486 // static
ForFixedArrayElement()487 ElementAccess AccessBuilder::ForFixedArrayElement() {
488 ElementAccess access = {kTaggedBase, FixedArray::kHeaderSize, Type::Tagged(),
489 MachineType::AnyTagged(), kFullWriteBarrier};
490 return access;
491 }
492
493
494 // static
ForFixedDoubleArrayElement()495 ElementAccess AccessBuilder::ForFixedDoubleArrayElement() {
496 ElementAccess access = {kTaggedBase, FixedDoubleArray::kHeaderSize,
497 TypeCache::Get().kFloat64, MachineType::Float64(),
498 kNoWriteBarrier};
499 return access;
500 }
501
502
503 // static
ForTypedArrayElement(ExternalArrayType type,bool is_external)504 ElementAccess AccessBuilder::ForTypedArrayElement(ExternalArrayType type,
505 bool is_external) {
506 BaseTaggedness taggedness = is_external ? kUntaggedBase : kTaggedBase;
507 int header_size = is_external ? 0 : FixedTypedArrayBase::kDataOffset;
508 switch (type) {
509 case kExternalInt8Array: {
510 ElementAccess access = {taggedness, header_size, Type::Signed32(),
511 MachineType::Int8(), kNoWriteBarrier};
512 return access;
513 }
514 case kExternalUint8Array:
515 case kExternalUint8ClampedArray: {
516 ElementAccess access = {taggedness, header_size, Type::Unsigned32(),
517 MachineType::Uint8(), kNoWriteBarrier};
518 return access;
519 }
520 case kExternalInt16Array: {
521 ElementAccess access = {taggedness, header_size, Type::Signed32(),
522 MachineType::Int16(), kNoWriteBarrier};
523 return access;
524 }
525 case kExternalUint16Array: {
526 ElementAccess access = {taggedness, header_size, Type::Unsigned32(),
527 MachineType::Uint16(), kNoWriteBarrier};
528 return access;
529 }
530 case kExternalInt32Array: {
531 ElementAccess access = {taggedness, header_size, Type::Signed32(),
532 MachineType::Int32(), kNoWriteBarrier};
533 return access;
534 }
535 case kExternalUint32Array: {
536 ElementAccess access = {taggedness, header_size, Type::Unsigned32(),
537 MachineType::Uint32(), kNoWriteBarrier};
538 return access;
539 }
540 case kExternalFloat32Array: {
541 ElementAccess access = {taggedness, header_size, Type::Number(),
542 MachineType::Float32(), kNoWriteBarrier};
543 return access;
544 }
545 case kExternalFloat64Array: {
546 ElementAccess access = {taggedness, header_size, Type::Number(),
547 MachineType::Float64(), kNoWriteBarrier};
548 return access;
549 }
550 }
551 UNREACHABLE();
552 ElementAccess access = {kUntaggedBase, 0, Type::None(), MachineType::None(),
553 kNoWriteBarrier};
554 return access;
555 }
556
557 } // namespace compiler
558 } // namespace internal
559 } // namespace v8
560