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 : OBJECT_CONSTRUCTORS_IMPL(DeoptimizationData, FixedArray)
28 : OBJECT_CONSTRUCTORS_IMPL(BytecodeArray, FixedArrayBase)
29 : OBJECT_CONSTRUCTORS_IMPL(AbstractCode, HeapObject)
30 : OBJECT_CONSTRUCTORS_IMPL(DependentCode, WeakFixedArray)
31 : OBJECT_CONSTRUCTORS_IMPL(CodeDataContainer, HeapObject)
32 : OBJECT_CONSTRUCTORS_IMPL(SourcePositionTableWithFrameCache, Tuple2)
33 :
34 : NEVER_READ_ONLY_SPACE_IMPL(AbstractCode)
35 :
36 : CAST_ACCESSOR(AbstractCode)
37 : CAST_ACCESSOR(BytecodeArray)
38 1471133 : CAST_ACCESSOR(Code)
39 : CAST_ACCESSOR(CodeDataContainer)
40 : CAST_ACCESSOR(DependentCode)
41 : CAST_ACCESSOR(DeoptimizationData)
42 : CAST_ACCESSOR(SourcePositionTableWithFrameCache)
43 :
44 269711 : ACCESSORS(SourcePositionTableWithFrameCache, source_position_table, ByteArray,
45 : kSourcePositionTableIndex)
46 98733 : 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 661179 : int AbstractCode::InstructionSize() {
58 1322358 : if (IsCode()) {
59 316184 : return GetCode()->InstructionSize();
60 : } else {
61 : return GetBytecodeArray()->length();
62 : }
63 : }
64 :
65 2142737 : ByteArray AbstractCode::source_position_table() {
66 4285474 : if (IsCode()) {
67 103528 : return GetCode()->SourcePositionTable();
68 : } else {
69 2039209 : return GetBytecodeArray()->SourcePositionTable();
70 : }
71 : }
72 :
73 72406 : Object AbstractCode::stack_frame_cache() {
74 : Object maybe_table;
75 144812 : if (IsCode()) {
76 : maybe_table = GetCode()->source_position_table();
77 : } else {
78 : maybe_table = GetBytecodeArray()->source_position_table();
79 : }
80 72406 : if (maybe_table->IsSourcePositionTableWithFrameCache()) {
81 : return SourcePositionTableWithFrameCache::cast(maybe_table)
82 56018 : ->stack_frame_cache();
83 : }
84 16388 : 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 : return GetCode()->ExecutableSize();
97 : } else {
98 : return GetBytecodeArray()->BytecodeArraySize();
99 : }
100 : }
101 :
102 24 : Address AbstractCode::raw_instruction_start() {
103 48 : if (IsCode()) {
104 : return GetCode()->raw_instruction_start();
105 : } else {
106 : return GetBytecodeArray()->GetFirstBytecodeAddress();
107 : }
108 : }
109 :
110 1293551 : Address AbstractCode::InstructionStart() {
111 2587102 : if (IsCode()) {
112 573474 : return GetCode()->InstructionStart();
113 : } else {
114 : return GetBytecodeArray()->GetFirstBytecodeAddress();
115 : }
116 : }
117 :
118 15 : Address AbstractCode::raw_instruction_end() {
119 30 : if (IsCode()) {
120 : return GetCode()->raw_instruction_end();
121 : } else {
122 12 : return GetBytecodeArray()->GetFirstBytecodeAddress() +
123 12 : 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 : bool AbstractCode::contains(Address inner_pointer) {
137 20 : return (address() <= inner_pointer) && (inner_pointer <= address() + Size());
138 : }
139 :
140 89664 : AbstractCode::Kind AbstractCode::kind() {
141 179328 : if (IsCode()) {
142 : return static_cast<AbstractCode::Kind>(GetCode()->kind());
143 : } else {
144 : return INTERPRETED_FUNCTION;
145 : }
146 : }
147 :
148 : Code AbstractCode::GetCode() { return Code::cast(*this); }
149 :
150 : BytecodeArray AbstractCode::GetBytecodeArray() {
151 : return BytecodeArray::cast(*this);
152 : }
153 :
154 : DependentCode DependentCode::next_link() {
155 : return DependentCode::cast(Get(kNextLinkIndex)->GetHeapObjectAssumeStrong());
156 : }
157 :
158 : void DependentCode::set_next_link(DependentCode next) {
159 138211 : Set(kNextLinkIndex, HeapObjectReference::Strong(next));
160 : }
161 :
162 : int DependentCode::flags() { return Smi::ToInt(Get(kFlagsIndex)->ToSmi()); }
163 :
164 : void DependentCode::set_flags(int flags) {
165 374940 : Set(kFlagsIndex, MaybeObject::FromObject(Smi::FromInt(flags)));
166 : }
167 :
168 666329 : int DependentCode::count() { return CountField::decode(flags()); }
169 :
170 267336 : void DependentCode::set_count(int value) {
171 534672 : set_flags(CountField::update(flags(), value));
172 267336 : }
173 :
174 : DependentCode::DependencyGroup DependentCode::group() {
175 9 : return static_cast<DependencyGroup>(GroupField::decode(flags()));
176 : }
177 :
178 : void DependentCode::set_object_at(int i, MaybeObject object) {
179 310866 : Set(kCodesStartIndex + i, object);
180 : }
181 :
182 : MaybeObject DependentCode::object_at(int i) {
183 : return Get(kCodesStartIndex + i);
184 : }
185 :
186 13577 : void DependentCode::clear_at(int i) {
187 13577 : Set(kCodesStartIndex + i,
188 27154 : HeapObjectReference::Strong(GetReadOnlyRoots().undefined_value()));
189 13577 : }
190 :
191 1707 : void DependentCode::copy(int from, int to) {
192 1707 : Set(kCodesStartIndex + to, Get(kCodesStartIndex + from));
193 1707 : }
194 :
195 2942266 : OBJECT_CONSTRUCTORS_IMPL(Code, HeapObject)
196 : NEVER_READ_ONLY_SPACE_IMPL(Code)
197 :
198 440598521 : INT_ACCESSORS(Code, raw_instruction_size, kInstructionSizeOffset)
199 4936099 : INT_ACCESSORS(Code, safepoint_table_offset, kSafepointTableOffsetOffset)
200 6675167 : INT_ACCESSORS(Code, handler_table_offset, kHandlerTableOffsetOffset)
201 6074017 : 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 10778287 : CODE_ACCESSORS(relocation_info, ByteArray, kRelocationInfoOffset)
210 14514035 : CODE_ACCESSORS(deoptimization_data, FixedArray, kDeoptimizationDataOffset)
211 11016139 : CODE_ACCESSORS(source_position_table, Object, kSourcePositionTableOffset)
212 : // Concurrent marker needs to access kind specific flags in code data container.
213 26808307 : SYNCHRONIZED_CODE_ACCESSORS(code_data_container, CodeDataContainer,
214 : kCodeDataContainerOffset)
215 : #undef CODE_ACCESSORS
216 : #undef SYNCHRONIZED_CODE_ACCESSORS
217 :
218 397771 : void Code::WipeOutHeader() {
219 397771 : WRITE_FIELD(*this, kRelocationInfoOffset, Smi::FromInt(0));
220 397771 : WRITE_FIELD(*this, kDeoptimizationDataOffset, Smi::FromInt(0));
221 397771 : WRITE_FIELD(*this, kSourcePositionTableOffset, Smi::FromInt(0));
222 397771 : WRITE_FIELD(*this, kCodeDataContainerOffset, Smi::FromInt(0));
223 397771 : }
224 :
225 1906428 : void Code::clear_padding() {
226 : if (FIELD_SIZE(kOptionalPaddingOffset) != 0) {
227 : memset(reinterpret_cast<void*>(address() + kOptionalPaddingOffset), 0,
228 : FIELD_SIZE(kOptionalPaddingOffset));
229 : }
230 : Address data_end =
231 1906428 : has_unwinding_info() ? unwinding_info_end() : raw_instruction_end();
232 3812856 : memset(reinterpret_cast<void*>(data_end), 0,
233 1906428 : CodeSize() - (data_end - address()));
234 1906428 : }
235 :
236 : ByteArray Code::SourcePositionTableIfCollected() const {
237 : ReadOnlyRoots roots = GetReadOnlyRoots();
238 : Object maybe_table = source_position_table();
239 : if (maybe_table->IsUndefined(roots) || maybe_table->IsException(roots))
240 : return roots.empty_byte_array();
241 : return SourcePositionTable();
242 : }
243 :
244 107323 : ByteArray Code::SourcePositionTable() const {
245 : Object maybe_table = source_position_table();
246 : DCHECK(!maybe_table->IsUndefined() && !maybe_table->IsException());
247 107323 : if (maybe_table->IsByteArray()) return ByteArray::cast(maybe_table);
248 : DCHECK(maybe_table->IsSourcePositionTableWithFrameCache());
249 : return SourcePositionTableWithFrameCache::cast(maybe_table)
250 : ->source_position_table();
251 : }
252 :
253 : Object Code::next_code_link() const {
254 : return code_data_container()->next_code_link();
255 : }
256 :
257 781981 : void Code::set_next_code_link(Object value) {
258 781981 : code_data_container()->set_next_code_link(value);
259 781981 : }
260 :
261 : int Code::InstructionSize() const {
262 166552 : if (is_off_heap_trampoline()) {
263 : DCHECK(FLAG_embedded_builtins);
264 64937 : return OffHeapInstructionSize();
265 : }
266 : return raw_instruction_size();
267 : }
268 :
269 : Address Code::raw_instruction_start() const {
270 288084219 : return FIELD_ADDR(*this, kHeaderSize);
271 : }
272 :
273 : Address Code::InstructionStart() const {
274 164408292 : if (is_off_heap_trampoline()) {
275 : DCHECK(FLAG_embedded_builtins);
276 154680318 : return OffHeapInstructionStart();
277 : }
278 : return raw_instruction_start();
279 : }
280 :
281 : Address Code::raw_instruction_end() const {
282 1906661 : return raw_instruction_start() + raw_instruction_size();
283 : }
284 :
285 252 : Address Code::InstructionEnd() const {
286 252 : if (is_off_heap_trampoline()) {
287 : DCHECK(FLAG_embedded_builtins);
288 0 : return OffHeapInstructionEnd();
289 : }
290 252 : return raw_instruction_end();
291 : }
292 :
293 : int Code::GetUnwindingInfoSizeOffset() const {
294 : DCHECK(has_unwinding_info());
295 121 : return RoundUp(kHeaderSize + raw_instruction_size(), kInt64Size);
296 : }
297 :
298 : int Code::unwinding_info_size() const {
299 : DCHECK(has_unwinding_info());
300 : return static_cast<int>(
301 67 : READ_UINT64_FIELD(*this, GetUnwindingInfoSizeOffset()));
302 : }
303 :
304 : void Code::set_unwinding_info_size(int value) {
305 : DCHECK(has_unwinding_info());
306 27 : WRITE_UINT64_FIELD(*this, GetUnwindingInfoSizeOffset(), value);
307 : }
308 :
309 : Address Code::unwinding_info_start() const {
310 : DCHECK(has_unwinding_info());
311 94 : return FIELD_ADDR(*this, GetUnwindingInfoSizeOffset()) + kInt64Size;
312 : }
313 :
314 : Address Code::unwinding_info_end() const {
315 : DCHECK(has_unwinding_info());
316 67 : return unwinding_info_start() + unwinding_info_size();
317 : }
318 :
319 432941814 : int Code::body_size() const {
320 : int unpadded_body_size =
321 : has_unwinding_info()
322 : ? static_cast<int>(unwinding_info_end() - raw_instruction_start())
323 432941884 : : raw_instruction_size();
324 432941814 : return RoundUp(unpadded_body_size, kObjectAlignment);
325 : }
326 :
327 0 : int Code::SizeIncludingMetadata() const {
328 : int size = CodeSize();
329 0 : size += relocation_info()->Size();
330 0 : size += deoptimization_data()->Size();
331 0 : return size;
332 : }
333 :
334 : ByteArray Code::unchecked_relocation_info() const {
335 210025890 : return ByteArray::unchecked_cast(READ_FIELD(*this, kRelocationInfoOffset));
336 : }
337 :
338 : byte* Code::relocation_start() const {
339 : return unchecked_relocation_info()->GetDataStartAddress();
340 : }
341 :
342 : byte* Code::relocation_end() const {
343 : return unchecked_relocation_info()->GetDataEndAddress();
344 : }
345 :
346 : int Code::relocation_size() const {
347 : return unchecked_relocation_info()->length();
348 : }
349 :
350 : Address Code::entry() const { return raw_instruction_start(); }
351 :
352 10960813 : bool Code::contains(Address inner_pointer) {
353 10960813 : if (is_off_heap_trampoline()) {
354 : DCHECK(FLAG_embedded_builtins);
355 1052307 : if (OffHeapInstructionStart() <= inner_pointer &&
356 390771 : inner_pointer < OffHeapInstructionEnd()) {
357 : return true;
358 : }
359 : }
360 10592407 : return (address() <= inner_pointer) && (inner_pointer < address() + Size());
361 : }
362 :
363 : int Code::ExecutableSize() const {
364 : // Check that the assumptions about the layout of the code object holds.
365 : DCHECK_EQ(static_cast<int>(raw_instruction_start() - address()),
366 : Code::kHeaderSize);
367 2 : return raw_instruction_size() + Code::kHeaderSize;
368 : }
369 :
370 : // static
371 : void Code::CopyRelocInfoToByteArray(ByteArray dest, const CodeDesc& desc) {
372 : DCHECK_EQ(dest->length(), desc.reloc_size);
373 3812964 : CopyBytes(dest->GetDataStartAddress(),
374 1906482 : desc.buffer + desc.buffer_size - desc.reloc_size,
375 : static_cast<size_t>(desc.reloc_size));
376 : }
377 :
378 432697722 : int Code::CodeSize() const { return SizeFor(body_size()); }
379 :
380 : Code::Kind Code::kind() const {
381 69108495 : return KindField::decode(READ_UINT32_FIELD(*this, kFlagsOffset));
382 : }
383 :
384 1991604 : void Code::initialize_flags(Kind kind, bool has_unwinding_info,
385 : bool is_turbofanned, int stack_slots,
386 : bool is_off_heap_trampoline) {
387 1991604 : CHECK(0 <= stack_slots && stack_slots < StackSlotsField::kMax);
388 : static_assert(Code::NUMBER_OF_KINDS <= KindField::kMax + 1, "field overflow");
389 1991604 : uint32_t flags = HasUnwindingInfoField::encode(has_unwinding_info) |
390 1991604 : KindField::encode(kind) |
391 1991604 : IsTurbofannedField::encode(is_turbofanned) |
392 : StackSlotsField::encode(stack_slots) |
393 1991604 : IsOffHeapTrampoline::encode(is_off_heap_trampoline);
394 1991604 : WRITE_UINT32_FIELD(*this, kFlagsOffset, flags);
395 : DCHECK_IMPLIES(stack_slots != 0, has_safepoint_info());
396 1991604 : }
397 :
398 : inline bool Code::is_interpreter_trampoline_builtin() const {
399 : bool is_interpreter_trampoline =
400 1620003 : (builtin_index() == Builtins::kInterpreterEntryTrampoline ||
401 30435293 : builtin_index() == Builtins::kInterpreterEnterBytecodeAdvance ||
402 : builtin_index() == Builtins::kInterpreterEnterBytecodeDispatch);
403 : return is_interpreter_trampoline;
404 : }
405 :
406 : inline bool Code::checks_optimization_marker() const {
407 : bool checks_marker =
408 : (builtin_index() == Builtins::kCompileLazy ||
409 : builtin_index() == Builtins::kInterpreterEntryTrampoline);
410 : return checks_marker ||
411 : (kind() == OPTIMIZED_FUNCTION && marked_for_deoptimization());
412 : }
413 :
414 : inline bool Code::has_tagged_params() const {
415 1411599 : return kind() != JS_TO_WASM_FUNCTION && kind() != C_WASM_ENTRY &&
416 : kind() != WASM_FUNCTION;
417 : }
418 :
419 : inline bool Code::has_unwinding_info() const {
420 434848256 : return HasUnwindingInfoField::decode(READ_UINT32_FIELD(*this, kFlagsOffset));
421 : }
422 :
423 : inline bool Code::is_turbofanned() const {
424 222900 : return IsTurbofannedField::decode(READ_UINT32_FIELD(*this, kFlagsOffset));
425 : }
426 :
427 381571 : inline bool Code::can_have_weak_objects() const {
428 : DCHECK(kind() == OPTIMIZED_FUNCTION);
429 : int32_t flags = code_data_container()->kind_specific_flags();
430 381571 : return CanHaveWeakObjectsField::decode(flags);
431 : }
432 :
433 460467 : inline void Code::set_can_have_weak_objects(bool value) {
434 : DCHECK(kind() == OPTIMIZED_FUNCTION);
435 : int32_t previous = code_data_container()->kind_specific_flags();
436 : int32_t updated = CanHaveWeakObjectsField::update(previous, value);
437 : code_data_container()->set_kind_specific_flags(updated);
438 460467 : }
439 :
440 7055 : inline bool Code::is_promise_rejection() const {
441 : DCHECK(kind() == BUILTIN);
442 : int32_t flags = code_data_container()->kind_specific_flags();
443 7055 : return IsPromiseRejectionField::decode(flags);
444 : }
445 :
446 784 : inline void Code::set_is_promise_rejection(bool value) {
447 : DCHECK(kind() == BUILTIN);
448 : int32_t previous = code_data_container()->kind_specific_flags();
449 : int32_t updated = IsPromiseRejectionField::update(previous, value);
450 : code_data_container()->set_kind_specific_flags(updated);
451 784 : }
452 :
453 5242 : inline bool Code::is_exception_caught() const {
454 : DCHECK(kind() == BUILTIN);
455 : int32_t flags = code_data_container()->kind_specific_flags();
456 5242 : return IsExceptionCaughtField::decode(flags);
457 : }
458 :
459 56 : inline void Code::set_is_exception_caught(bool value) {
460 : DCHECK(kind() == BUILTIN);
461 : int32_t previous = code_data_container()->kind_specific_flags();
462 : int32_t updated = IsExceptionCaughtField::update(previous, value);
463 : code_data_container()->set_kind_specific_flags(updated);
464 56 : }
465 :
466 : inline bool Code::is_off_heap_trampoline() const {
467 172678849 : return IsOffHeapTrampoline::decode(READ_UINT32_FIELD(*this, kFlagsOffset));
468 : }
469 :
470 7055 : inline HandlerTable::CatchPrediction Code::GetBuiltinCatchPrediction() {
471 7055 : if (is_promise_rejection()) return HandlerTable::PROMISE;
472 5242 : if (is_exception_caught()) return HandlerTable::CAUGHT;
473 5174 : return HandlerTable::UNCAUGHT;
474 : }
475 :
476 : int Code::builtin_index() const {
477 197312161 : int index = READ_INT_FIELD(*this, kBuiltinIndexOffset);
478 : DCHECK(index == -1 || Builtins::IsBuiltinId(index));
479 : return index;
480 : }
481 :
482 : void Code::set_builtin_index(int index) {
483 : DCHECK(index == -1 || Builtins::IsBuiltinId(index));
484 1991604 : WRITE_INT_FIELD(*this, kBuiltinIndexOffset, index);
485 : }
486 :
487 : bool Code::is_builtin() const { return builtin_index() != -1; }
488 :
489 : bool Code::has_safepoint_info() const {
490 105417 : return is_turbofanned() || is_wasm_code();
491 : }
492 :
493 : int Code::stack_slots() const {
494 : DCHECK(has_safepoint_info());
495 7445447 : return StackSlotsField::decode(READ_UINT32_FIELD(*this, kFlagsOffset));
496 : }
497 :
498 4952992 : bool Code::marked_for_deoptimization() const {
499 : DCHECK(kind() == OPTIMIZED_FUNCTION);
500 : int32_t flags = code_data_container()->kind_specific_flags();
501 4952992 : return MarkedForDeoptimizationField::decode(flags);
502 : }
503 :
504 318573 : void Code::set_marked_for_deoptimization(bool flag) {
505 : DCHECK(kind() == OPTIMIZED_FUNCTION);
506 : DCHECK_IMPLIES(flag, AllowDeoptimization::IsAllowed(GetIsolate()));
507 : int32_t previous = code_data_container()->kind_specific_flags();
508 : int32_t updated = MarkedForDeoptimizationField::update(previous, flag);
509 : code_data_container()->set_kind_specific_flags(updated);
510 318573 : }
511 :
512 870 : bool Code::embedded_objects_cleared() const {
513 : DCHECK(kind() == OPTIMIZED_FUNCTION);
514 : int32_t flags = code_data_container()->kind_specific_flags();
515 870 : return EmbeddedObjectsClearedField::decode(flags);
516 : }
517 :
518 291 : void Code::set_embedded_objects_cleared(bool flag) {
519 : DCHECK(kind() == OPTIMIZED_FUNCTION);
520 : DCHECK_IMPLIES(flag, marked_for_deoptimization());
521 : int32_t previous = code_data_container()->kind_specific_flags();
522 : int32_t updated = EmbeddedObjectsClearedField::update(previous, flag);
523 : code_data_container()->set_kind_specific_flags(updated);
524 291 : }
525 :
526 90669 : bool Code::deopt_already_counted() const {
527 : DCHECK(kind() == OPTIMIZED_FUNCTION);
528 : int32_t flags = code_data_container()->kind_specific_flags();
529 90669 : return DeoptAlreadyCountedField::decode(flags);
530 : }
531 :
532 69501 : void Code::set_deopt_already_counted(bool flag) {
533 : DCHECK(kind() == OPTIMIZED_FUNCTION);
534 : DCHECK_IMPLIES(flag, AllowDeoptimization::IsAllowed(GetIsolate()));
535 : int32_t previous = code_data_container()->kind_specific_flags();
536 : int32_t updated = DeoptAlreadyCountedField::update(previous, flag);
537 : code_data_container()->set_kind_specific_flags(updated);
538 69501 : }
539 :
540 : bool Code::is_optimized_code() const { return kind() == OPTIMIZED_FUNCTION; }
541 : bool Code::is_wasm_code() const { return kind() == WASM_FUNCTION; }
542 :
543 : int Code::constant_pool_offset() const {
544 : if (!FLAG_enable_embedded_constant_pool) return code_comments_offset();
545 : return READ_INT_FIELD(*this, kConstantPoolOffsetOffset);
546 : }
547 :
548 : void Code::set_constant_pool_offset(int value) {
549 : if (!FLAG_enable_embedded_constant_pool) return;
550 : DCHECK_LE(value, InstructionSize());
551 : WRITE_INT_FIELD(*this, kConstantPoolOffsetOffset, value);
552 : }
553 :
554 208958188 : Address Code::constant_pool() const {
555 208958188 : if (!has_constant_pool()) return kNullAddress;
556 0 : return InstructionStart() + constant_pool_offset();
557 : }
558 :
559 8 : Address Code::code_comments() const {
560 8 : return InstructionStart() + code_comments_offset();
561 : }
562 :
563 3144021 : Code Code::GetCodeFromTargetAddress(Address address) {
564 : {
565 : // TODO(jgruber,v8:6666): Support embedded builtins here. We'd need to pass
566 : // in the current isolate.
567 3144021 : Address start = reinterpret_cast<Address>(Isolate::CurrentEmbeddedBlob());
568 3144012 : Address end = start + Isolate::CurrentEmbeddedBlobSize();
569 3143999 : CHECK(address < start || address >= end);
570 : }
571 :
572 : HeapObject code = HeapObject::FromAddress(address - Code::kHeaderSize);
573 : // Unchecked cast because we can't rely on the map currently
574 : // not being a forwarding pointer.
575 3143999 : return Code::unchecked_cast(code);
576 : }
577 :
578 : Code Code::GetObjectFromEntryAddress(Address location_of_address) {
579 0 : Address code_entry = Memory<Address>(location_of_address);
580 : HeapObject code = HeapObject::FromAddress(code_entry - Code::kHeaderSize);
581 : // Unchecked cast because we can't rely on the map currently
582 : // not being a forwarding pointer.
583 : return Code::unchecked_cast(code);
584 : }
585 :
586 382806 : bool Code::CanContainWeakObjects() {
587 382806 : return is_optimized_code() && can_have_weak_objects();
588 : }
589 :
590 382809 : bool Code::IsWeakObject(HeapObject object) {
591 382809 : return (CanContainWeakObjects() && IsWeakObjectInOptimizedCode(object));
592 : }
593 :
594 5466739 : bool Code::IsWeakObjectInOptimizedCode(HeapObject object) {
595 : Map map = object->synchronized_map();
596 : InstanceType instance_type = map->instance_type();
597 5466739 : if (InstanceTypeChecker::IsMap(instance_type)) {
598 : return Map::cast(object)->CanTransition();
599 : }
600 5270933 : return InstanceTypeChecker::IsPropertyCell(instance_type) ||
601 10380240 : InstanceTypeChecker::IsJSReceiver(instance_type) ||
602 : InstanceTypeChecker::IsContext(instance_type);
603 : }
604 :
605 : // This field has to have relaxed atomic accessors because it is accessed in the
606 : // concurrent marker.
607 9214591 : RELAXED_INT32_ACCESSORS(CodeDataContainer, kind_specific_flags,
608 : kKindSpecificFlagsOffset)
609 15552670 : ACCESSORS(CodeDataContainer, next_code_link, Object, kNextCodeLinkOffset)
610 :
611 : void CodeDataContainer::clear_padding() {
612 1906462 : memset(reinterpret_cast<void*>(address() + kUnalignedSize), 0,
613 : kSize - kUnalignedSize);
614 : }
615 :
616 : byte BytecodeArray::get(int index) const {
617 : DCHECK(index >= 0 && index < this->length());
618 277610393 : return READ_BYTE_FIELD(*this, kHeaderSize + index * kCharSize);
619 : }
620 :
621 : void BytecodeArray::set(int index, byte value) {
622 : DCHECK(index >= 0 && index < this->length());
623 14273385 : WRITE_BYTE_FIELD(*this, kHeaderSize + index * kCharSize, value);
624 : }
625 :
626 : void BytecodeArray::set_frame_size(int frame_size) {
627 : DCHECK_GE(frame_size, 0);
628 : DCHECK(IsAligned(frame_size, kSystemPointerSize));
629 2122111 : WRITE_INT_FIELD(*this, kFrameSizeOffset, frame_size);
630 : }
631 :
632 : int BytecodeArray::frame_size() const {
633 30232214 : return READ_INT_FIELD(*this, kFrameSizeOffset);
634 : }
635 :
636 : int BytecodeArray::register_count() const {
637 30219262 : return frame_size() / kSystemPointerSize;
638 : }
639 :
640 : void BytecodeArray::set_parameter_count(int number_of_parameters) {
641 : DCHECK_GE(number_of_parameters, 0);
642 : // Parameter count is stored as the size on stack of the parameters to allow
643 : // it to be used directly by generated code.
644 4244222 : WRITE_INT_FIELD(*this, kParameterSizeOffset,
645 4244222 : (number_of_parameters << kSystemPointerSizeLog2));
646 : }
647 :
648 : interpreter::Register BytecodeArray::incoming_new_target_or_generator_register()
649 : const {
650 : int register_operand =
651 540716 : READ_INT_FIELD(*this, kIncomingNewTargetOrGeneratorRegisterOffset);
652 540716 : if (register_operand == 0) {
653 : return interpreter::Register::invalid_value();
654 : } else {
655 : return interpreter::Register::FromOperand(register_operand);
656 : }
657 : }
658 :
659 : void BytecodeArray::set_incoming_new_target_or_generator_register(
660 : interpreter::Register incoming_new_target_or_generator_register) {
661 115803 : if (!incoming_new_target_or_generator_register.is_valid()) {
662 2121538 : WRITE_INT_FIELD(*this, kIncomingNewTargetOrGeneratorRegisterOffset, 0);
663 : } else {
664 : DCHECK(incoming_new_target_or_generator_register.index() <
665 : register_count());
666 : DCHECK_NE(0, incoming_new_target_or_generator_register.ToOperand());
667 105775 : WRITE_INT_FIELD(*this, kIncomingNewTargetOrGeneratorRegisterOffset,
668 211550 : incoming_new_target_or_generator_register.ToOperand());
669 : }
670 : }
671 :
672 : int BytecodeArray::osr_loop_nesting_level() const {
673 41144 : return READ_INT8_FIELD(*this, kOSRNestingLevelOffset);
674 : }
675 :
676 : void BytecodeArray::set_osr_loop_nesting_level(int depth) {
677 : DCHECK(0 <= depth && depth <= AbstractCode::kMaxLoopNestingMarker);
678 : STATIC_ASSERT(AbstractCode::kMaxLoopNestingMarker < kMaxInt8);
679 2165304 : WRITE_INT8_FIELD(*this, kOSRNestingLevelOffset, depth);
680 : }
681 :
682 : BytecodeArray::Age BytecodeArray::bytecode_age() const {
683 : // Bytecode is aged by the concurrent marker.
684 5403159 : return static_cast<Age>(RELAXED_READ_INT8_FIELD(*this, kBytecodeAgeOffset));
685 : }
686 :
687 : void BytecodeArray::set_bytecode_age(BytecodeArray::Age age) {
688 : DCHECK_GE(age, kFirstBytecodeAge);
689 : DCHECK_LE(age, kLastBytecodeAge);
690 : STATIC_ASSERT(kLastBytecodeAge <= kMaxInt8);
691 : // Bytecode is aged by the concurrent marker.
692 2122116 : RELAXED_WRITE_INT8_FIELD(*this, kBytecodeAgeOffset, static_cast<int8_t>(age));
693 : }
694 :
695 : int BytecodeArray::parameter_count() const {
696 : // Parameter count is stored as the size on stack of the parameters to allow
697 : // it to be used directly by generated code.
698 1745678 : return READ_INT_FIELD(*this, kParameterSizeOffset) >> kSystemPointerSizeLog2;
699 : }
700 :
701 15589110 : ACCESSORS(BytecodeArray, constant_pool, FixedArray, kConstantPoolOffset)
702 59496374 : ACCESSORS(BytecodeArray, handler_table, ByteArray, kHandlerTableOffset)
703 30729677 : ACCESSORS(BytecodeArray, source_position_table, Object,
704 : kSourcePositionTableOffset)
705 :
706 2111503 : void BytecodeArray::clear_padding() {
707 2111503 : int data_size = kHeaderSize + length();
708 4223006 : memset(reinterpret_cast<void*>(address() + data_size), 0,
709 2111503 : SizeFor(length()) - data_size);
710 2111503 : }
711 :
712 : Address BytecodeArray::GetFirstBytecodeAddress() {
713 34048585 : return ptr() - kHeapObjectTag + kHeaderSize;
714 : }
715 :
716 2622117 : bool BytecodeArray::HasSourcePositionTable() const {
717 : Object maybe_table = source_position_table();
718 5244152 : return !(maybe_table->IsUndefined() || DidSourcePositionGenerationFail());
719 : }
720 :
721 : bool BytecodeArray::DidSourcePositionGenerationFail() const {
722 : return source_position_table()->IsException();
723 : }
724 :
725 5 : void BytecodeArray::SetSourcePositionsFailedToCollect() {
726 5 : set_source_position_table(GetReadOnlyRoots().exception());
727 5 : }
728 :
729 6800557 : ByteArray BytecodeArray::SourcePositionTable() const {
730 : Object maybe_table = source_position_table();
731 6800557 : if (maybe_table->IsByteArray()) return ByteArray::cast(maybe_table);
732 : ReadOnlyRoots roots = GetReadOnlyRoots();
733 228718 : if (maybe_table->IsException(roots)) return roots.empty_byte_array();
734 :
735 : DCHECK(!maybe_table->IsUndefined(roots));
736 : DCHECK(maybe_table->IsSourcePositionTableWithFrameCache());
737 : return SourcePositionTableWithFrameCache::cast(maybe_table)
738 : ->source_position_table();
739 : }
740 :
741 530027 : ByteArray BytecodeArray::SourcePositionTableIfCollected() const {
742 530027 : if (!HasSourcePositionTable()) return GetReadOnlyRoots().empty_byte_array();
743 :
744 530021 : return SourcePositionTable();
745 : }
746 :
747 1529 : void BytecodeArray::ClearFrameCacheFromSourcePositionTable() {
748 : Object maybe_table = source_position_table();
749 3058 : if (maybe_table->IsUndefined() || maybe_table->IsByteArray()) return;
750 : DCHECK(maybe_table->IsSourcePositionTableWithFrameCache());
751 : set_source_position_table(SourcePositionTableWithFrameCache::cast(maybe_table)
752 0 : ->source_position_table());
753 : }
754 :
755 : int BytecodeArray::BytecodeArraySize() { return SizeFor(this->length()); }
756 :
757 2092015 : int BytecodeArray::SizeIncludingMetadata() {
758 : int size = BytecodeArraySize();
759 2092015 : size += constant_pool()->Size();
760 2092027 : size += handler_table()->Size();
761 2092027 : if (HasSourcePositionTable()) {
762 4183966 : size += SourcePositionTable()->Size();
763 : }
764 2092028 : return size;
765 : }
766 :
767 463911 : DEFINE_DEOPT_ELEMENT_ACCESSORS(TranslationByteArray, ByteArray)
768 : DEFINE_DEOPT_ELEMENT_ACCESSORS(InlinedFunctionCount, Smi)
769 463912 : DEFINE_DEOPT_ELEMENT_ACCESSORS(LiteralArray, FixedArray)
770 : DEFINE_DEOPT_ELEMENT_ACCESSORS(OsrBytecodeOffset, Smi)
771 9266 : DEFINE_DEOPT_ELEMENT_ACCESSORS(OsrPcOffset, Smi)
772 : DEFINE_DEOPT_ELEMENT_ACCESSORS(OptimizationId, Smi)
773 464120 : DEFINE_DEOPT_ELEMENT_ACCESSORS(InliningPositions, PodArray<InliningPosition>)
774 :
775 : DEFINE_DEOPT_ENTRY_ACCESSORS(BytecodeOffsetRaw, Smi)
776 1461399 : DEFINE_DEOPT_ENTRY_ACCESSORS(TranslationIndex, Smi)
777 87353 : DEFINE_DEOPT_ENTRY_ACCESSORS(Pc, Smi)
778 :
779 59463 : BailoutId DeoptimizationData::BytecodeOffset(int i) {
780 59463 : return BailoutId(BytecodeOffsetRaw(i)->value());
781 : }
782 :
783 : void DeoptimizationData::SetBytecodeOffset(int i, BailoutId value) {
784 : SetBytecodeOffsetRaw(i, Smi::FromInt(value.ToInt()));
785 : }
786 :
787 : int DeoptimizationData::DeoptCount() {
788 88767 : return (length() - kFirstDeoptEntryIndex) / kDeoptEntrySize;
789 : }
790 :
791 : } // namespace internal
792 : } // namespace v8
793 :
794 : #include "src/objects/object-macros-undef.h"
795 :
796 : #endif // V8_OBJECTS_CODE_INL_H_
|