Line data Source code
1 : // Copyright 2017 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_CODE_INL_H_
6 : #define V8_OBJECTS_CODE_INL_H_
7 :
8 : #include "src/objects/code.h"
9 :
10 : #include "src/code-desc.h"
11 : #include "src/interpreter/bytecode-register.h"
12 : #include "src/isolate.h"
13 : #include "src/objects/dictionary.h"
14 : #include "src/objects/instance-type-inl.h"
15 : #include "src/objects/map-inl.h"
16 : #include "src/objects/maybe-object-inl.h"
17 : #include "src/objects/oddball.h"
18 : #include "src/objects/smi-inl.h"
19 : #include "src/v8memory.h"
20 :
21 : // Has to be the last include (doesn't have include guards):
22 : #include "src/objects/object-macros.h"
23 :
24 : namespace v8 {
25 : namespace internal {
26 :
27 9375948 : OBJECT_CONSTRUCTORS_IMPL(DeoptimizationData, FixedArray)
28 330080668 : OBJECT_CONSTRUCTORS_IMPL(BytecodeArray, FixedArrayBase)
29 32878882 : OBJECT_CONSTRUCTORS_IMPL(AbstractCode, HeapObject)
30 113458252 : OBJECT_CONSTRUCTORS_IMPL(DependentCode, WeakFixedArray)
31 270846752 : OBJECT_CONSTRUCTORS_IMPL(CodeDataContainer, HeapObject)
32 594114 : OBJECT_CONSTRUCTORS_IMPL(SourcePositionTableWithFrameCache, Tuple2)
33 :
34 : NEVER_READ_ONLY_SPACE_IMPL(AbstractCode)
35 :
36 16494598 : CAST_ACCESSOR(AbstractCode)
37 165048574 : CAST_ACCESSOR(BytecodeArray)
38 569708919 : CAST_ACCESSOR(Code)
39 135988811 : CAST_ACCESSOR(CodeDataContainer)
40 56730615 : CAST_ACCESSOR(DependentCode)
41 4687973 : CAST_ACCESSOR(DeoptimizationData)
42 297057 : CAST_ACCESSOR(SourcePositionTableWithFrameCache)
43 :
44 724399 : ACCESSORS(SourcePositionTableWithFrameCache, source_position_table, ByteArray,
45 : kSourcePositionTableIndex)
46 224457 : ACCESSORS(SourcePositionTableWithFrameCache, stack_frame_cache,
47 : SimpleNumberDictionary, kStackFrameCacheIndex)
48 :
49 : int AbstractCode::raw_instruction_size() {
50 : if (IsCode()) {
51 : return GetCode()->raw_instruction_size();
52 : } else {
53 : return GetBytecodeArray()->length();
54 : }
55 : }
56 :
57 660830 : int AbstractCode::InstructionSize() {
58 1321660 : if (IsCode()) {
59 158024 : return GetCode()->InstructionSize();
60 : } else {
61 1005612 : return GetBytecodeArray()->length();
62 : }
63 : }
64 :
65 2134993 : ByteArray AbstractCode::source_position_table() {
66 4269986 : if (IsCode()) {
67 103104 : return GetCode()->SourcePositionTable();
68 : } else {
69 2031889 : return GetBytecodeArray()->SourcePositionTable();
70 : }
71 : }
72 :
73 76951 : Object AbstractCode::stack_frame_cache() {
74 76951 : Object maybe_table;
75 153902 : if (IsCode()) {
76 0 : maybe_table = GetCode()->source_position_table();
77 : } else {
78 153902 : maybe_table = GetBytecodeArray()->source_position_table();
79 : }
80 76951 : if (maybe_table->IsSourcePositionTableWithFrameCache()) {
81 : return SourcePositionTableWithFrameCache::cast(maybe_table)
82 60669 : ->stack_frame_cache();
83 : }
84 16282 : return Smi::kZero;
85 : }
86 :
87 0 : int AbstractCode::SizeIncludingMetadata() {
88 0 : if (IsCode()) {
89 0 : return GetCode()->SizeIncludingMetadata();
90 : } else {
91 0 : return GetBytecodeArray()->SizeIncludingMetadata();
92 : }
93 : }
94 10 : int AbstractCode::ExecutableSize() {
95 20 : if (IsCode()) {
96 4 : return GetCode()->ExecutableSize();
97 : } else {
98 8 : return GetBytecodeArray()->BytecodeArraySize();
99 : }
100 : }
101 :
102 24 : Address AbstractCode::raw_instruction_start() {
103 48 : if (IsCode()) {
104 14 : return GetCode()->raw_instruction_start();
105 : } else {
106 34 : return GetBytecodeArray()->GetFirstBytecodeAddress();
107 : }
108 : }
109 :
110 1292280 : Address AbstractCode::InstructionStart() {
111 2584560 : if (IsCode()) {
112 286034 : return GetCode()->InstructionStart();
113 : } else {
114 2012492 : return GetBytecodeArray()->GetFirstBytecodeAddress();
115 : }
116 : }
117 :
118 15 : Address AbstractCode::raw_instruction_end() {
119 30 : if (IsCode()) {
120 6 : return GetCode()->raw_instruction_end();
121 : } else {
122 36 : return GetBytecodeArray()->GetFirstBytecodeAddress() +
123 24 : GetBytecodeArray()->length();
124 : }
125 : }
126 :
127 : Address AbstractCode::InstructionEnd() {
128 : if (IsCode()) {
129 : return GetCode()->InstructionEnd();
130 : } else {
131 : return GetBytecodeArray()->GetFirstBytecodeAddress() +
132 : GetBytecodeArray()->length();
133 : }
134 : }
135 :
136 20 : bool AbstractCode::contains(Address inner_pointer) {
137 20 : return (address() <= inner_pointer) && (inner_pointer <= address() + Size());
138 : }
139 :
140 92050 : AbstractCode::Kind AbstractCode::kind() {
141 184100 : if (IsCode()) {
142 177610 : return static_cast<AbstractCode::Kind>(GetCode()->kind());
143 : } else {
144 : return INTERPRETED_FUNCTION;
145 : }
146 : }
147 :
148 2894850 : Code AbstractCode::GetCode() { return Code::cast(*this); }
149 :
150 3629507 : BytecodeArray AbstractCode::GetBytecodeArray() {
151 3629507 : return BytecodeArray::cast(*this);
152 : }
153 :
154 66903 : DependentCode DependentCode::next_link() {
155 133806 : return DependentCode::cast(Get(kNextLinkIndex)->GetHeapObjectAssumeStrong());
156 : }
157 :
158 : void DependentCode::set_next_link(DependentCode next) {
159 94525 : Set(kNextLinkIndex, HeapObjectReference::Strong(next));
160 : }
161 :
162 1728416 : int DependentCode::flags() { return Smi::ToInt(Get(kFlagsIndex)->ToSmi()); }
163 :
164 : void DependentCode::set_flags(int flags) {
165 327751 : Set(kFlagsIndex, MaybeObject::FromObject(Smi::FromInt(flags)));
166 : }
167 :
168 554063 : int DependentCode::count() { return CountField::decode(flags()); }
169 :
170 243338 : void DependentCode::set_count(int value) {
171 486676 : set_flags(CountField::update(flags(), value));
172 243338 : }
173 :
174 : DependentCode::DependencyGroup DependentCode::group() {
175 931024 : return static_cast<DependencyGroup>(GroupField::decode(flags()));
176 : }
177 :
178 : void DependentCode::set_object_at(int i, MaybeObject object) {
179 272003 : Set(kCodesStartIndex + i, object);
180 : }
181 :
182 : MaybeObject DependentCode::object_at(int i) {
183 45707679 : return Get(kCodesStartIndex + i);
184 : }
185 :
186 17928 : void DependentCode::clear_at(int i) {
187 : Set(kCodesStartIndex + i,
188 35856 : HeapObjectReference::Strong(GetReadOnlyRoots().undefined_value()));
189 17928 : }
190 :
191 3106 : void DependentCode::copy(int from, int to) {
192 3106 : Set(kCodesStartIndex + to, Get(kCodesStartIndex + from));
193 3106 : }
194 :
195 1133655981 : OBJECT_CONSTRUCTORS_IMPL(Code, HeapObject)
196 : NEVER_READ_ONLY_SPACE_IMPL(Code)
197 :
198 496309562 : INT_ACCESSORS(Code, raw_instruction_size, kInstructionSizeOffset)
199 4922499 : INT_ACCESSORS(Code, safepoint_table_offset, kSafepointTableOffsetOffset)
200 6709157 : INT_ACCESSORS(Code, handler_table_offset, kHandlerTableOffsetOffset)
201 6116335 : INT_ACCESSORS(Code, code_comments_offset, kCodeCommentsOffsetOffset)
202 : #define CODE_ACCESSORS(name, type, offset) \
203 : ACCESSORS_CHECKED2(Code, name, type, offset, true, \
204 : !ObjectInYoungGeneration(value))
205 : #define SYNCHRONIZED_CODE_ACCESSORS(name, type, offset) \
206 : SYNCHRONIZED_ACCESSORS_CHECKED2(Code, name, type, offset, true, \
207 : !ObjectInYoungGeneration(value))
208 :
209 14104630 : CODE_ACCESSORS(relocation_info, ByteArray, kRelocationInfoOffset)
210 22937480 : CODE_ACCESSORS(deoptimization_data, FixedArray, kDeoptimizationDataOffset)
211 11515652 : CODE_ACCESSORS(source_position_table, Object, kSourcePositionTableOffset)
212 : // Concurrent marker needs to access kind specific flags in code data container.
213 61079663 : SYNCHRONIZED_CODE_ACCESSORS(code_data_container, CodeDataContainer,
214 : kCodeDataContainerOffset)
215 : #undef CODE_ACCESSORS
216 : #undef SYNCHRONIZED_CODE_ACCESSORS
217 :
218 386055 : void Code::WipeOutHeader() {
219 386055 : WRITE_FIELD(*this, kRelocationInfoOffset, Smi::FromInt(0));
220 386055 : WRITE_FIELD(*this, kDeoptimizationDataOffset, Smi::FromInt(0));
221 386055 : WRITE_FIELD(*this, kSourcePositionTableOffset, Smi::FromInt(0));
222 386055 : WRITE_FIELD(*this, kCodeDataContainerOffset, Smi::FromInt(0));
223 386055 : }
224 :
225 1893229 : void Code::clear_padding() {
226 1893229 : memset(reinterpret_cast<void*>(address() + kHeaderPaddingStart), 0,
227 1893229 : kHeaderSize - kHeaderPaddingStart);
228 : Address data_end =
229 1893229 : has_unwinding_info() ? unwinding_info_end() : raw_instruction_end();
230 : memset(reinterpret_cast<void*>(data_end), 0,
231 3786458 : CodeSize() - (data_end - address()));
232 1893229 : }
233 :
234 109438 : ByteArray Code::SourcePositionTable() const {
235 109438 : Object maybe_table = source_position_table();
236 109438 : if (maybe_table->IsByteArray()) return ByteArray::cast(maybe_table);
237 : DCHECK(maybe_table->IsSourcePositionTableWithFrameCache());
238 : return SourcePositionTableWithFrameCache::cast(maybe_table)
239 0 : ->source_position_table();
240 : }
241 :
242 : Object Code::next_code_link() const {
243 17259500 : return code_data_container()->next_code_link();
244 : }
245 :
246 765743 : void Code::set_next_code_link(Object value) {
247 765743 : code_data_container()->set_next_code_link(value);
248 765743 : }
249 :
250 168979 : int Code::InstructionSize() const {
251 168979 : if (is_off_heap_trampoline()) {
252 : DCHECK(FLAG_embedded_builtins);
253 67549 : return OffHeapInstructionSize();
254 : }
255 101430 : return raw_instruction_size();
256 : }
257 :
258 488936 : Address Code::raw_instruction_start() const {
259 294470821 : return FIELD_ADDR(*this, kHeaderSize);
260 : }
261 :
262 164037553 : Address Code::InstructionStart() const {
263 164037553 : if (is_off_heap_trampoline()) {
264 : DCHECK(FLAG_embedded_builtins);
265 154391176 : return OffHeapInstructionStart();
266 : }
267 9646377 : return raw_instruction_start();
268 : }
269 :
270 : Address Code::raw_instruction_end() const {
271 1893457 : return raw_instruction_start() + raw_instruction_size();
272 : }
273 :
274 247 : Address Code::InstructionEnd() const {
275 247 : if (is_off_heap_trampoline()) {
276 : DCHECK(FLAG_embedded_builtins);
277 0 : return OffHeapInstructionEnd();
278 : }
279 247 : return raw_instruction_end();
280 : }
281 :
282 : int Code::GetUnwindingInfoSizeOffset() const {
283 : DCHECK(has_unwinding_info());
284 134 : return RoundUp(kHeaderSize + raw_instruction_size(), kInt64Size);
285 : }
286 :
287 : int Code::unwinding_info_size() const {
288 : DCHECK(has_unwinding_info());
289 : return static_cast<int>(
290 70 : READ_UINT64_FIELD(*this, GetUnwindingInfoSizeOffset()));
291 : }
292 :
293 : void Code::set_unwinding_info_size(int value) {
294 : DCHECK(has_unwinding_info());
295 27 : WRITE_UINT64_FIELD(*this, GetUnwindingInfoSizeOffset(), value);
296 : }
297 :
298 : Address Code::unwinding_info_start() const {
299 : DCHECK(has_unwinding_info());
300 102 : return FIELD_ADDR(*this, GetUnwindingInfoSizeOffset()) + kInt64Size;
301 : }
302 :
303 : Address Code::unwinding_info_end() const {
304 : DCHECK(has_unwinding_info());
305 65 : return unwinding_info_start() + unwinding_info_size();
306 : }
307 :
308 488704891 : int Code::body_size() const {
309 : int unpadded_body_size =
310 : has_unwinding_info()
311 : ? static_cast<int>(unwinding_info_end() - raw_instruction_start())
312 488704957 : : raw_instruction_size();
313 488704891 : return RoundUp(unpadded_body_size, kObjectAlignment);
314 : }
315 :
316 0 : int Code::SizeIncludingMetadata() const {
317 : int size = CodeSize();
318 0 : size += relocation_info()->Size();
319 0 : size += deoptimization_data()->Size();
320 0 : return size;
321 : }
322 :
323 : ByteArray Code::unchecked_relocation_info() const {
324 215962023 : return ByteArray::unchecked_cast(READ_FIELD(*this, kRelocationInfoOffset));
325 : }
326 :
327 : byte* Code::relocation_start() const {
328 : return unchecked_relocation_info()->GetDataStartAddress();
329 : }
330 :
331 : byte* Code::relocation_end() const {
332 0 : return unchecked_relocation_info()->GetDataEndAddress();
333 : }
334 :
335 85033 : int Code::relocation_size() const {
336 85033 : return unchecked_relocation_info()->length();
337 : }
338 :
339 : Address Code::entry() const { return raw_instruction_start(); }
340 :
341 10467890 : bool Code::contains(Address inner_pointer) {
342 10467890 : if (is_off_heap_trampoline()) {
343 : DCHECK(FLAG_embedded_builtins);
344 430715 : if (OffHeapInstructionStart() <= inner_pointer &&
345 95506 : inner_pointer < OffHeapInstructionEnd()) {
346 : return true;
347 : }
348 : }
349 10384495 : return (address() <= inner_pointer) && (inner_pointer < address() + Size());
350 : }
351 :
352 : int Code::ExecutableSize() const {
353 : // Check that the assumptions about the layout of the code object holds.
354 : DCHECK_EQ(static_cast<int>(raw_instruction_start() - address()),
355 : Code::kHeaderSize);
356 2 : return raw_instruction_size() + Code::kHeaderSize;
357 : }
358 :
359 : // static
360 : void Code::CopyRelocInfoToByteArray(ByteArray dest, const CodeDesc& desc) {
361 : DCHECK_EQ(dest->length(), desc.reloc_size);
362 : CopyBytes(dest->GetDataStartAddress(),
363 1893285 : desc.buffer + desc.buffer_size - desc.reloc_size,
364 5679855 : static_cast<size_t>(desc.reloc_size));
365 : }
366 :
367 488493762 : int Code::CodeSize() const { return SizeFor(body_size()); }
368 :
369 5017 : Code::Kind Code::kind() const {
370 68476658 : return KindField::decode(READ_UINT32_FIELD(*this, kFlagsOffset));
371 : }
372 :
373 1977509 : void Code::initialize_flags(Kind kind, bool has_unwinding_info,
374 : bool is_turbofanned, int stack_slots,
375 : bool is_off_heap_trampoline) {
376 1977509 : CHECK(0 <= stack_slots && stack_slots < StackSlotsField::kMax);
377 : static_assert(Code::NUMBER_OF_KINDS <= KindField::kMax + 1, "field overflow");
378 1977509 : uint32_t flags = HasUnwindingInfoField::encode(has_unwinding_info) |
379 1977509 : KindField::encode(kind) |
380 1977509 : IsTurbofannedField::encode(is_turbofanned) |
381 : StackSlotsField::encode(stack_slots) |
382 1977509 : IsOffHeapTrampoline::encode(is_off_heap_trampoline);
383 1977509 : WRITE_UINT32_FIELD(*this, kFlagsOffset, flags);
384 : DCHECK_IMPLIES(stack_slots != 0, has_safepoint_info());
385 1977509 : }
386 :
387 : inline bool Code::is_interpreter_trampoline_builtin() const {
388 : bool is_interpreter_trampoline =
389 1604287 : (builtin_index() == Builtins::kInterpreterEntryTrampoline ||
390 30115724 : builtin_index() == Builtins::kInterpreterEnterBytecodeAdvance ||
391 : builtin_index() == Builtins::kInterpreterEnterBytecodeDispatch);
392 : return is_interpreter_trampoline;
393 : }
394 :
395 : inline bool Code::checks_optimization_marker() const {
396 : bool checks_marker =
397 : (builtin_index() == Builtins::kCompileLazy ||
398 : builtin_index() == Builtins::kInterpreterEntryTrampoline);
399 : return checks_marker ||
400 : (kind() == OPTIMIZED_FUNCTION && marked_for_deoptimization());
401 : }
402 :
403 : inline bool Code::has_tagged_params() const {
404 1215491 : return kind() != JS_TO_WASM_FUNCTION && kind() != C_WASM_ENTRY &&
405 : kind() != WASM_FUNCTION;
406 : }
407 :
408 : inline bool Code::has_unwinding_info() const {
409 490682414 : return HasUnwindingInfoField::decode(READ_UINT32_FIELD(*this, kFlagsOffset));
410 : }
411 :
412 4745 : inline bool Code::is_turbofanned() const {
413 228295 : return IsTurbofannedField::decode(READ_UINT32_FIELD(*this, kFlagsOffset));
414 : }
415 :
416 499792 : inline bool Code::can_have_weak_objects() const {
417 : DCHECK(kind() == OPTIMIZED_FUNCTION);
418 999582 : int32_t flags = code_data_container()->kind_specific_flags();
419 499790 : return CanHaveWeakObjectsField::decode(flags);
420 : }
421 :
422 453149 : inline void Code::set_can_have_weak_objects(bool value) {
423 : DCHECK(kind() == OPTIMIZED_FUNCTION);
424 906298 : int32_t previous = code_data_container()->kind_specific_flags();
425 : int32_t updated = CanHaveWeakObjectsField::update(previous, value);
426 906298 : code_data_container()->set_kind_specific_flags(updated);
427 453149 : }
428 :
429 6975 : inline bool Code::is_promise_rejection() const {
430 : DCHECK(kind() == BUILTIN);
431 13950 : int32_t flags = code_data_container()->kind_specific_flags();
432 6975 : return IsPromiseRejectionField::decode(flags);
433 : }
434 :
435 784 : inline void Code::set_is_promise_rejection(bool value) {
436 : DCHECK(kind() == BUILTIN);
437 784 : int32_t previous = code_data_container()->kind_specific_flags();
438 784 : int32_t updated = IsPromiseRejectionField::update(previous, value);
439 784 : code_data_container()->set_kind_specific_flags(updated);
440 784 : }
441 :
442 5162 : inline bool Code::is_exception_caught() const {
443 : DCHECK(kind() == BUILTIN);
444 10324 : int32_t flags = code_data_container()->kind_specific_flags();
445 5162 : return IsExceptionCaughtField::decode(flags);
446 : }
447 :
448 56 : inline void Code::set_is_exception_caught(bool value) {
449 : DCHECK(kind() == BUILTIN);
450 56 : int32_t previous = code_data_container()->kind_specific_flags();
451 56 : int32_t updated = IsExceptionCaughtField::update(previous, value);
452 56 : code_data_container()->set_kind_specific_flags(updated);
453 56 : }
454 :
455 : inline bool Code::is_off_heap_trampoline() const {
456 205659341 : return IsOffHeapTrampoline::decode(READ_UINT32_FIELD(*this, kFlagsOffset));
457 : }
458 :
459 6975 : inline HandlerTable::CatchPrediction Code::GetBuiltinCatchPrediction() {
460 6975 : if (is_promise_rejection()) return HandlerTable::PROMISE;
461 5162 : if (is_exception_caught()) return HandlerTable::CAUGHT;
462 5094 : return HandlerTable::UNCAUGHT;
463 : }
464 :
465 832384 : int Code::builtin_index() const {
466 227386956 : int index = READ_INT_FIELD(*this, kBuiltinIndexOffset);
467 : DCHECK(index == -1 || Builtins::IsBuiltinId(index));
468 832384 : return index;
469 : }
470 :
471 : void Code::set_builtin_index(int index) {
472 : DCHECK(index == -1 || Builtins::IsBuiltinId(index));
473 1977509 : WRITE_INT_FIELD(*this, kBuiltinIndexOffset, index);
474 : }
475 :
476 416192 : bool Code::is_builtin() const { return builtin_index() != -1; }
477 :
478 : bool Code::has_safepoint_info() const {
479 109551 : return is_turbofanned() || is_wasm_code();
480 : }
481 :
482 : int Code::stack_slots() const {
483 : DCHECK(has_safepoint_info());
484 7365079 : return StackSlotsField::decode(READ_UINT32_FIELD(*this, kFlagsOffset));
485 : }
486 :
487 4968258 : bool Code::marked_for_deoptimization() const {
488 : DCHECK(kind() == OPTIMIZED_FUNCTION);
489 9936516 : int32_t flags = code_data_container()->kind_specific_flags();
490 4968258 : return MarkedForDeoptimizationField::decode(flags);
491 : }
492 :
493 309524 : void Code::set_marked_for_deoptimization(bool flag) {
494 : DCHECK(kind() == OPTIMIZED_FUNCTION);
495 : DCHECK_IMPLIES(flag, AllowDeoptimization::IsAllowed(GetIsolate()));
496 619048 : int32_t previous = code_data_container()->kind_specific_flags();
497 : int32_t updated = MarkedForDeoptimizationField::update(previous, flag);
498 619048 : code_data_container()->set_kind_specific_flags(updated);
499 309524 : }
500 :
501 832 : bool Code::embedded_objects_cleared() const {
502 : DCHECK(kind() == OPTIMIZED_FUNCTION);
503 1664 : int32_t flags = code_data_container()->kind_specific_flags();
504 832 : return EmbeddedObjectsClearedField::decode(flags);
505 : }
506 :
507 266 : void Code::set_embedded_objects_cleared(bool flag) {
508 : DCHECK(kind() == OPTIMIZED_FUNCTION);
509 : DCHECK_IMPLIES(flag, marked_for_deoptimization());
510 532 : int32_t previous = code_data_container()->kind_specific_flags();
511 : int32_t updated = EmbeddedObjectsClearedField::update(previous, flag);
512 532 : code_data_container()->set_kind_specific_flags(updated);
513 266 : }
514 :
515 82157 : bool Code::deopt_already_counted() const {
516 : DCHECK(kind() == OPTIMIZED_FUNCTION);
517 164314 : int32_t flags = code_data_container()->kind_specific_flags();
518 82157 : return DeoptAlreadyCountedField::decode(flags);
519 : }
520 :
521 61344 : void Code::set_deopt_already_counted(bool flag) {
522 : DCHECK(kind() == OPTIMIZED_FUNCTION);
523 : DCHECK_IMPLIES(flag, AllowDeoptimization::IsAllowed(GetIsolate()));
524 122688 : int32_t previous = code_data_container()->kind_specific_flags();
525 : int32_t updated = DeoptAlreadyCountedField::update(previous, flag);
526 122688 : code_data_container()->set_kind_specific_flags(updated);
527 61344 : }
528 :
529 : bool Code::is_optimized_code() const { return kind() == OPTIMIZED_FUNCTION; }
530 : bool Code::is_wasm_code() const { return kind() == WASM_FUNCTION; }
531 :
532 : int Code::constant_pool_offset() const {
533 : if (!FLAG_enable_embedded_constant_pool) return code_comments_offset();
534 : return READ_INT_FIELD(*this, kConstantPoolOffsetOffset);
535 : }
536 :
537 : void Code::set_constant_pool_offset(int value) {
538 : if (!FLAG_enable_embedded_constant_pool) return;
539 : DCHECK_LE(value, InstructionSize());
540 : WRITE_INT_FIELD(*this, kConstantPoolOffsetOffset, value);
541 : }
542 :
543 214877137 : Address Code::constant_pool() const {
544 214877137 : if (!has_constant_pool()) return kNullAddress;
545 0 : return InstructionStart() + constant_pool_offset();
546 : }
547 :
548 8 : Address Code::code_comments() const {
549 8 : if (!has_code_comments()) return kNullAddress;
550 16 : return InstructionStart() + code_comments_offset();
551 : }
552 :
553 3315994 : Code Code::GetCodeFromTargetAddress(Address address) {
554 : {
555 : // TODO(jgruber,v8:6666): Support embedded builtins here. We'd need to pass
556 : // in the current isolate.
557 3315994 : Address start = reinterpret_cast<Address>(Isolate::CurrentEmbeddedBlob());
558 3316000 : Address end = start + Isolate::CurrentEmbeddedBlobSize();
559 3315994 : CHECK(address < start || address >= end);
560 : }
561 :
562 416192 : HeapObject code = HeapObject::FromAddress(address - Code::kHeaderSize);
563 : // Unchecked cast because we can't rely on the map currently
564 : // not being a forwarding pointer.
565 3315994 : return Code::unchecked_cast(code);
566 : }
567 :
568 : Code Code::GetObjectFromEntryAddress(Address location_of_address) {
569 0 : Address code_entry = Memory<Address>(location_of_address);
570 : HeapObject code = HeapObject::FromAddress(code_entry - Code::kHeaderSize);
571 : // Unchecked cast because we can't rely on the map currently
572 : // not being a forwarding pointer.
573 : return Code::unchecked_cast(code);
574 : }
575 :
576 501021 : bool Code::CanContainWeakObjects() {
577 501021 : return is_optimized_code() && can_have_weak_objects();
578 : }
579 :
580 501014 : bool Code::IsWeakObject(HeapObject object) {
581 501014 : return (CanContainWeakObjects() && IsWeakObjectInOptimizedCode(object));
582 : }
583 :
584 5554961 : bool Code::IsWeakObjectInOptimizedCode(HeapObject object) {
585 : Map map = object->synchronized_map();
586 : InstanceType instance_type = map->instance_type();
587 5554961 : if (InstanceTypeChecker::IsMap(instance_type)) {
588 : return Map::cast(object)->CanTransition();
589 : }
590 5336992 : return InstanceTypeChecker::IsPropertyCell(instance_type) ||
591 10509993 : InstanceTypeChecker::IsJSReceiver(instance_type) ||
592 5387026 : InstanceTypeChecker::IsContext(instance_type);
593 : }
594 :
595 : // This field has to have relaxed atomic accessors because it is accessed in the
596 : // concurrent marker.
597 9275288 : RELAXED_INT32_ACCESSORS(CodeDataContainer, kind_specific_flags,
598 : kKindSpecificFlagsOffset)
599 19184931 : ACCESSORS(CodeDataContainer, next_code_link, Object, kNextCodeLinkOffset)
600 :
601 1893268 : void CodeDataContainer::clear_padding() {
602 1893268 : memset(reinterpret_cast<void*>(address() + kUnalignedSize), 0,
603 1893268 : kSize - kUnalignedSize);
604 1893268 : }
605 :
606 66643 : byte BytecodeArray::get(int index) const {
607 : DCHECK(index >= 0 && index < this->length());
608 304174404 : return READ_BYTE_FIELD(*this, kHeaderSize + index * kCharSize);
609 : }
610 :
611 : void BytecodeArray::set(int index, byte value) {
612 : DCHECK(index >= 0 && index < this->length());
613 14273890 : WRITE_BYTE_FIELD(*this, kHeaderSize + index * kCharSize, value);
614 : }
615 :
616 : void BytecodeArray::set_frame_size(int frame_size) {
617 : DCHECK_GE(frame_size, 0);
618 : DCHECK(IsAligned(frame_size, kSystemPointerSize));
619 2093560 : WRITE_INT_FIELD(*this, kFrameSizeOffset, frame_size);
620 : }
621 :
622 : int BytecodeArray::frame_size() const {
623 30972073 : return READ_INT_FIELD(*this, kFrameSizeOffset);
624 : }
625 :
626 8653 : int BytecodeArray::register_count() const {
627 30959145 : return frame_size() / kSystemPointerSize;
628 : }
629 :
630 : void BytecodeArray::set_parameter_count(int number_of_parameters) {
631 : DCHECK_GE(number_of_parameters, 0);
632 : // Parameter count is stored as the size on stack of the parameters to allow
633 : // it to be used directly by generated code.
634 4187114 : WRITE_INT_FIELD(*this, kParameterSizeOffset,
635 4187114 : (number_of_parameters << kSystemPointerSizeLog2));
636 : }
637 :
638 : interpreter::Register BytecodeArray::incoming_new_target_or_generator_register()
639 : const {
640 : int register_operand =
641 533484 : READ_INT_FIELD(*this, kIncomingNewTargetOrGeneratorRegisterOffset);
642 533484 : if (register_operand == 0) {
643 : return interpreter::Register::invalid_value();
644 : } else {
645 : return interpreter::Register::FromOperand(register_operand);
646 : }
647 : }
648 :
649 : void BytecodeArray::set_incoming_new_target_or_generator_register(
650 : interpreter::Register incoming_new_target_or_generator_register) {
651 116101 : if (!incoming_new_target_or_generator_register.is_valid()) {
652 2092984 : WRITE_INT_FIELD(*this, kIncomingNewTargetOrGeneratorRegisterOffset, 0);
653 : } else {
654 : DCHECK(incoming_new_target_or_generator_register.index() <
655 : register_count());
656 : DCHECK_NE(0, incoming_new_target_or_generator_register.ToOperand());
657 106097 : WRITE_INT_FIELD(*this, kIncomingNewTargetOrGeneratorRegisterOffset,
658 212194 : incoming_new_target_or_generator_register.ToOperand());
659 : }
660 : }
661 :
662 : int BytecodeArray::interrupt_budget() const {
663 10582 : return READ_INT_FIELD(*this, kInterruptBudgetOffset);
664 : }
665 :
666 : void BytecodeArray::set_interrupt_budget(int interrupt_budget) {
667 : DCHECK_GE(interrupt_budget, 0);
668 2094298 : WRITE_INT_FIELD(*this, kInterruptBudgetOffset, interrupt_budget);
669 : }
670 :
671 : int BytecodeArray::osr_loop_nesting_level() const {
672 42238 : return READ_INT8_FIELD(*this, kOSRNestingLevelOffset);
673 : }
674 :
675 : void BytecodeArray::set_osr_loop_nesting_level(int depth) {
676 : DCHECK(0 <= depth && depth <= AbstractCode::kMaxLoopNestingMarker);
677 : STATIC_ASSERT(AbstractCode::kMaxLoopNestingMarker < kMaxInt8);
678 2138257 : WRITE_INT8_FIELD(*this, kOSRNestingLevelOffset, depth);
679 : }
680 :
681 : BytecodeArray::Age BytecodeArray::bytecode_age() const {
682 : // Bytecode is aged by the concurrent marker.
683 7783222 : return static_cast<Age>(RELAXED_READ_INT8_FIELD(*this, kBytecodeAgeOffset));
684 : }
685 :
686 : void BytecodeArray::set_bytecode_age(BytecodeArray::Age age) {
687 : DCHECK_GE(age, kFirstBytecodeAge);
688 : DCHECK_LE(age, kLastBytecodeAge);
689 : STATIC_ASSERT(kLastBytecodeAge <= kMaxInt8);
690 : // Bytecode is aged by the concurrent marker.
691 2093565 : RELAXED_WRITE_INT8_FIELD(*this, kBytecodeAgeOffset, static_cast<int8_t>(age));
692 : }
693 :
694 : int BytecodeArray::parameter_count() const {
695 : // Parameter count is stored as the size on stack of the parameters to allow
696 : // it to be used directly by generated code.
697 1728941 : return READ_INT_FIELD(*this, kParameterSizeOffset) >> kSystemPointerSizeLog2;
698 : }
699 :
700 26145160 : ACCESSORS(BytecodeArray, constant_pool, FixedArray, kConstantPoolOffset)
701 138727526 : ACCESSORS(BytecodeArray, handler_table, ByteArray, kHandlerTableOffset)
702 27782150 : ACCESSORS(BytecodeArray, source_position_table, Object,
703 : kSourcePositionTableOffset)
704 :
705 2082982 : void BytecodeArray::clear_padding() {
706 2082985 : int data_size = kHeaderSize + length();
707 2082983 : memset(reinterpret_cast<void*>(address() + data_size), 0,
708 4165966 : SizeFor(length()) - data_size);
709 2082983 : }
710 :
711 : Address BytecodeArray::GetFirstBytecodeAddress() {
712 35113823 : return ptr() - kHeapObjectTag + kHeaderSize;
713 : }
714 :
715 10 : bool BytecodeArray::HasSourcePositionTable() {
716 10 : Object maybe_table = source_position_table();
717 10 : return !maybe_table->IsUndefined();
718 : }
719 :
720 6756162 : ByteArray BytecodeArray::SourcePositionTable() {
721 6756162 : Object maybe_table = source_position_table();
722 6756170 : if (maybe_table->IsByteArray()) return ByteArray::cast(maybe_table);
723 227911 : ReadOnlyRoots roots = GetReadOnlyRoots();
724 227911 : if (maybe_table->IsUndefined(roots)) return roots.empty_byte_array();
725 :
726 : DCHECK(maybe_table->IsSourcePositionTableWithFrameCache());
727 : return SourcePositionTableWithFrameCache::cast(maybe_table)
728 227878 : ->source_position_table();
729 : }
730 :
731 1529 : void BytecodeArray::ClearFrameCacheFromSourcePositionTable() {
732 1529 : Object maybe_table = source_position_table();
733 4587 : if (maybe_table->IsUndefined() || maybe_table->IsByteArray()) return;
734 : DCHECK(maybe_table->IsSourcePositionTableWithFrameCache());
735 : set_source_position_table(SourcePositionTableWithFrameCache::cast(maybe_table)
736 0 : ->source_position_table());
737 : }
738 :
739 4127065 : int BytecodeArray::BytecodeArraySize() { return SizeFor(this->length()); }
740 :
741 2063520 : int BytecodeArray::SizeIncludingMetadata() {
742 2063520 : int size = BytecodeArraySize();
743 2063520 : size += constant_pool()->Size();
744 2063516 : size += handler_table()->Size();
745 2063516 : size += SourcePositionTable()->Size();
746 2063520 : return size;
747 : }
748 :
749 3335502 : DEFINE_DEOPT_ELEMENT_ACCESSORS(TranslationByteArray, ByteArray)
750 33962 : DEFINE_DEOPT_ELEMENT_ACCESSORS(InlinedFunctionCount, Smi)
751 3369638 : DEFINE_DEOPT_ELEMENT_ACCESSORS(LiteralArray, FixedArray)
752 : DEFINE_DEOPT_ELEMENT_ACCESSORS(OsrBytecodeOffset, Smi)
753 9954 : DEFINE_DEOPT_ELEMENT_ACCESSORS(OsrPcOffset, Smi)
754 492 : DEFINE_DEOPT_ELEMENT_ACCESSORS(OptimizationId, Smi)
755 456745 : DEFINE_DEOPT_ELEMENT_ACCESSORS(InliningPositions, PodArray<InliningPosition>)
756 :
757 6651512 : DEFINE_DEOPT_ENTRY_ACCESSORS(BytecodeOffsetRaw, Smi)
758 10863613 : DEFINE_DEOPT_ENTRY_ACCESSORS(TranslationIndex, Smi)
759 7047845 : DEFINE_DEOPT_ENTRY_ACCESSORS(Pc, Smi)
760 :
761 : BailoutId DeoptimizationData::BytecodeOffset(int i) {
762 106294 : return BailoutId(BytecodeOffsetRaw(i)->value());
763 : }
764 :
765 : void DeoptimizationData::SetBytecodeOffset(int i, BailoutId value) {
766 3272609 : SetBytecodeOffsetRaw(i, Smi::FromInt(value.ToInt()));
767 : }
768 :
769 100230 : int DeoptimizationData::DeoptCount() {
770 100230 : return (length() - kFirstDeoptEntryIndex) / kDeoptEntrySize;
771 : }
772 :
773 : } // namespace internal
774 : } // namespace v8
775 :
776 : #include "src/objects/object-macros-undef.h"
777 :
778 : #endif // V8_OBJECTS_CODE_INL_H_
|