[code] Update Code names and remove obsolete functions

- Remove camel-case Code accessors like InstructionStream since
  they only make sense on Code (where we have to distinguish between
  embedded builtins and other Code).
- Remove the prefix from 'raw_'-prefixed accessors since it was
  intended to clearly disambiguate from the camel-case accessors and
  is now no longer needed.
- Remove various dead functions.
- Update comments.

Bug: v8:13654
Change-Id: Ife51e4aef502fc30ab1526c205a49e5620be96f7
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4205925
Reviewed-by: Camillo Bruni <cbruni@chromium.org>
Commit-Queue: Jakob Linke <jgruber@chromium.org>
Reviewed-by: Dominik Inführ <dinfuehr@chromium.org>
Reviewed-by: Clemens Backes <clemensb@chromium.org>
Cr-Commit-Position: refs/heads/main@{#85580}
This commit is contained in:
Jakob Linke 2023-02-01 08:03:59 +01:00 committed by V8 LUCI CQ
parent ac99619606
commit cbbdf48bab
39 changed files with 369 additions and 539 deletions

View File

@ -250,8 +250,8 @@ void SetupIsolateDelegate::ReplacePlaceholders(Isolate* isolate) {
for (RelocIterator it(code, kRelocMask); !it.done(); it.next()) {
RelocInfo* rinfo = it.rinfo();
if (RelocInfo::IsCodeTargetMode(rinfo->rmode())) {
InstructionStream target = InstructionStream::GetCodeFromTargetAddress(
rinfo->target_address());
InstructionStream target =
InstructionStream::FromTargetAddress(rinfo->target_address());
DCHECK_IMPLIES(RelocInfo::IsRelativeCodeTarget(rinfo->rmode()),
Builtins::IsIsolateIndependent(target.builtin_id()));
if (!target.is_builtin()) continue;
@ -271,8 +271,7 @@ void SetupIsolateDelegate::ReplacePlaceholders(Isolate* isolate) {
flush_icache = true;
}
if (flush_icache) {
FlushInstructionCache(code.raw_instruction_start(),
code.raw_instruction_size());
FlushInstructionCache(code.instruction_start(), code.instruction_size());
}
}
}

View File

@ -18,9 +18,8 @@ namespace internal {
namespace {
template <typename CodeOrInstructionStream>
struct CodeOrInstructionStreamOps {
Handle<CodeOrInstructionStream> code;
struct CodeOps {
Handle<Code> code;
Address constant_pool() const { return code->constant_pool(); }
Address instruction_start() const { return code->InstructionStart(); }
@ -33,9 +32,6 @@ struct CodeOrInstructionStreamOps {
int code_comments_size() const { return code->code_comments_size(); }
};
using InstructionStreamOps = CodeOrInstructionStreamOps<InstructionStream>;
using CodeOps = CodeOrInstructionStreamOps<Code>;
#if V8_ENABLE_WEBASSEMBLY
struct WasmCodeOps {
const wasm::WasmCode* code;
@ -92,21 +88,19 @@ struct CodeDescOps {
#define HANDLE_WASM(...) UNREACHABLE()
#endif
#define DISPATCH(ret, method) \
ret CodeReference::method() const { \
DCHECK(!is_null()); \
switch (kind_) { \
case Kind::INSTRUCTION_STREAM: \
return InstructionStreamOps{instruction_stream_}.method(); \
case Kind::CODE: \
return CodeOps{code_}.method(); \
case Kind::WASM_CODE: \
HANDLE_WASM(return WasmCodeOps{wasm_code_}.method()); \
case Kind::CODE_DESC: \
return CodeDescOps{code_desc_}.method(); \
default: \
UNREACHABLE(); \
} \
#define DISPATCH(ret, method) \
ret CodeReference::method() const { \
DCHECK(!is_null()); \
switch (kind_) { \
case Kind::CODE: \
return CodeOps{code_}.method(); \
case Kind::WASM_CODE: \
HANDLE_WASM(return WasmCodeOps{wasm_code_}.method()); \
case Kind::CODE_DESC: \
return CodeDescOps{code_desc_}.method(); \
default: \
UNREACHABLE(); \
} \
}
DISPATCH(Address, constant_pool)

View File

@ -27,8 +27,6 @@ class CodeReference {
: kind_(Kind::WASM_CODE), wasm_code_(wasm_code) {}
explicit CodeReference(const CodeDesc* code_desc)
: kind_(Kind::CODE_DESC), code_desc_(code_desc) {}
explicit CodeReference(Handle<InstructionStream> code)
: kind_(Kind::INSTRUCTION_STREAM), instruction_stream_(code) {}
explicit CodeReference(Handle<Code> code) : kind_(Kind::CODE), code_(code) {}
Address constant_pool() const;
@ -42,17 +40,9 @@ class CodeReference {
int code_comments_size() const;
bool is_null() const { return kind_ == Kind::NONE; }
bool is_instruction_stream() const {
return kind_ == Kind::INSTRUCTION_STREAM;
}
bool is_code() const { return kind_ == Kind::CODE; }
bool is_wasm_code() const { return kind_ == Kind::WASM_CODE; }
Handle<InstructionStream> as_instruction_stream() const {
DCHECK_EQ(Kind::INSTRUCTION_STREAM, kind_);
return instruction_stream_;
}
Handle<Code> as_code() const {
DCHECK_EQ(Kind::CODE, kind_);
return code_;
@ -64,18 +54,11 @@ class CodeReference {
}
private:
enum class Kind {
NONE,
INSTRUCTION_STREAM,
CODE,
WASM_CODE,
CODE_DESC
} kind_;
enum class Kind { NONE, CODE, WASM_CODE, CODE_DESC } kind_;
union {
std::nullptr_t null_;
const wasm::WasmCode* wasm_code_;
const CodeDesc* code_desc_;
Handle<InstructionStream> instruction_stream_;
Handle<Code> code_;
};

View File

@ -20,7 +20,7 @@ namespace v8 {
namespace internal {
HandlerTable::HandlerTable(InstructionStream code)
: HandlerTable(code.HandlerTableAddress(), code.handler_table_size(),
: HandlerTable(code.handler_table_address(), code.handler_table_size(),
kReturnAddressBasedEncoding) {}
HandlerTable::HandlerTable(Code code)

View File

@ -14,8 +14,8 @@ namespace internal {
MaglevSafepointTable::MaglevSafepointTable(Isolate* isolate, Address pc,
InstructionStream code)
: MaglevSafepointTable(code.InstructionStart(isolate, pc),
code.SafepointTableAddress()) {
: MaglevSafepointTable(code.instruction_start(),
code.safepoint_table_address()) {
DCHECK(code.is_maglevved());
}

View File

@ -263,7 +263,7 @@ RelocIterator::RelocIterator(Code code, int mode_mask)
RelocIterator::RelocIterator(InstructionStream code, ByteArray relocation_info,
int mode_mask)
: RelocIterator(code, code.raw_instruction_start(), code.constant_pool(),
: RelocIterator(code, code.instruction_start(), code.constant_pool(),
relocation_info.GetDataEndAddress(),
relocation_info.GetDataStartAddress(), mode_mask) {}
@ -358,7 +358,7 @@ void RelocInfo::set_target_address(Address target,
if (!host().is_null() && IsCodeTargetMode(rmode_) &&
!v8_flags.disable_write_barriers) {
InstructionStream target_code =
InstructionStream::GetCodeFromTargetAddress(target);
InstructionStream::FromTargetAddress(target);
WriteBarrierForCode(host(), this, target_code, write_barrier_mode);
}
}
@ -470,8 +470,7 @@ void RelocInfo::Print(Isolate* isolate, std::ostream& os) {
<< ")";
} else if (IsCodeTargetMode(rmode_)) {
const Address code_target = target_address();
InstructionStream code =
InstructionStream::GetCodeFromTargetAddress(code_target);
InstructionStream code = InstructionStream::FromTargetAddress(code_target);
DCHECK(code.IsInstructionStream());
os << " (" << CodeKindToString(code.kind());
if (Builtins::IsBuiltin(code)) {
@ -501,8 +500,7 @@ void RelocInfo::Verify(Isolate* isolate) {
Address addr = target_address();
CHECK_NE(addr, kNullAddress);
// Check that we can find the right code object.
InstructionStream code =
InstructionStream::GetCodeFromTargetAddress(addr);
InstructionStream code = InstructionStream::FromTargetAddress(addr);
Code lookup_result = isolate->heap()->FindCodeForInnerPointer(addr);
CHECK_EQ(code.address(), lookup_result.instruction_stream().address());
break;
@ -513,8 +511,8 @@ void RelocInfo::Verify(Isolate* isolate) {
Address pc = target_internal_reference_address();
Code lookup_result = isolate->heap()->FindCodeForInnerPointer(pc);
InstructionStream code = lookup_result.instruction_stream();
CHECK(target >= code.InstructionStart(isolate, pc));
CHECK(target <= code.InstructionEnd(isolate, pc));
CHECK(target >= code.instruction_start());
CHECK(target < code.instruction_end());
break;
}
case OFF_HEAP_TARGET: {

View File

@ -22,8 +22,8 @@ namespace internal {
SafepointTable::SafepointTable(Isolate* isolate, Address pc,
InstructionStream code)
: SafepointTable(code.InstructionStart(isolate, pc),
code.SafepointTableAddress()) {}
: SafepointTable(code.instruction_start(), code.safepoint_table_address()) {
}
SafepointTable::SafepointTable(Isolate* isolate, Address pc, Code code)
: SafepointTable(code.InstructionStart(isolate, pc),

View File

@ -475,8 +475,8 @@ Deoptimizer::Deoptimizer(Isolate* isolate, JSFunction function,
DCHECK_GT(kLazyDeoptExitSize, 0);
DeoptimizationData deopt_data =
DeoptimizationData::cast(compiled_code_.deoptimization_data());
Address deopt_start = compiled_code_.raw_instruction_start() +
deopt_data.DeoptExitStart().value();
Address deopt_start =
compiled_code_.instruction_start() + deopt_data.DeoptExitStart().value();
int eager_deopt_count = deopt_data.EagerDeoptCount().value();
Address lazy_deopt_start =
deopt_start + eager_deopt_count * kEagerDeoptExitSize;
@ -1935,7 +1935,7 @@ unsigned Deoptimizer::ComputeIncomingArgumentSize(SharedFunctionInfo shared) {
Deoptimizer::DeoptInfo Deoptimizer::GetDeoptInfo(InstructionStream code,
Address pc) {
CHECK(code.InstructionStart() <= pc && pc <= code.InstructionEnd());
CHECK(code.instruction_start() <= pc && pc <= code.instruction_end());
SourcePosition last_position = SourcePosition::Unknown();
DeoptimizeReason last_reason = DeoptimizeReason::kUnknown;
uint32_t last_node_id = 0;

View File

@ -376,16 +376,16 @@ static int DecodeIt(Isolate* isolate, ExternalReferenceEncoder* ref_encoder,
// Print all the reloc info for this instruction which are not comments.
for (size_t i = 0; i < pcs.size(); i++) {
// Put together the reloc info
// Put together the reloc info.
const CodeReference& host = code;
Address constant_pool =
host.is_null() ? kNullAddress : host.constant_pool();
InstructionStream code_pointer;
if (host.is_instruction_stream()) {
code_pointer = *host.as_instruction_stream();
InstructionStream instruction_stream;
if (host.is_code()) {
instruction_stream = host.as_code()->instruction_stream();
}
RelocInfo relocinfo(pcs[i], rmodes[i], datas[i], code_pointer,
RelocInfo relocinfo(pcs[i], rmodes[i], datas[i], instruction_stream,
constant_pool);
bool first_reloc_info = (i == 0);

View File

@ -1101,12 +1101,12 @@ void Code::CodeVerify(Isolate* isolate) {
// object associated with this Code.
#ifdef V8_COMPRESS_POINTERS_IN_SHARED_CAGE
if (V8_SHORT_BUILTIN_CALLS_BOOL) {
if (istream.InstructionStart() == code_entry_point()) {
if (istream.instruction_start() == code_entry_point()) {
// Most common case, all good.
} else {
// When shared pointer compression cage is enabled and it has the
// embedded code blob copy then the
// InstructionStream::InstructionStart() might return the address of
// InstructionStream::instruction_start() might return the address of
// the remapped builtin regardless of whether the builtins copy existed
// when the code_entry_point value was cached in the Code (see
// InstructionStream::OffHeapInstructionStart()). So, do a reverse
@ -1117,31 +1117,31 @@ void Code::CodeVerify(Isolate* isolate) {
CHECK_EQ(lookup_result, *this);
}
} else {
CHECK_EQ(istream.InstructionStart(), code_entry_point());
CHECK_EQ(istream.instruction_start(), code_entry_point());
}
#else
CHECK_EQ(istream.InstructionStart(), code_entry_point());
CHECK_EQ(istream.instruction_start(), code_entry_point());
#endif // V8_COMPRESS_POINTERS_IN_SHARED_CAGE
}
}
void InstructionStream::InstructionStreamVerify(Isolate* isolate) {
CHECK(
IsAligned(InstructionSize(),
IsAligned(instruction_size(),
static_cast<unsigned>(InstructionStream::kMetadataAlignment)));
CHECK_EQ(safepoint_table_offset(), 0);
CHECK_LE(safepoint_table_offset(), handler_table_offset());
CHECK_LE(handler_table_offset(), constant_pool_offset());
CHECK_LE(constant_pool_offset(), code_comments_offset());
CHECK_LE(code_comments_offset(), unwinding_info_offset());
CHECK_LE(unwinding_info_offset(), MetadataSize());
CHECK_LE(unwinding_info_offset(), metadata_size());
#if !defined(_MSC_VER) || defined(__clang__)
// See also: PlatformEmbeddedFileWriterWin::AlignToCodeAlignment.
CHECK_IMPLIES(!ReadOnlyHeap::Contains(*this),
IsAligned(InstructionStart(), kCodeAlignment));
IsAligned(instruction_start(), kCodeAlignment));
#endif // !defined(_MSC_VER) || defined(__clang__)
CHECK_IMPLIES(!ReadOnlyHeap::Contains(*this),
IsAligned(raw_instruction_start(), kCodeAlignment));
IsAligned(instruction_start(), kCodeAlignment));
CHECK_EQ(*this, code(kAcquireLoad).instruction_stream());
relocation_info().ObjectVerify(isolate);
CHECK(V8_ENABLE_THIRD_PARTY_HEAP_BOOL ||

View File

@ -1794,13 +1794,14 @@ void PropertyCell::PropertyCellPrint(std::ostream& os) {
void InstructionStream::InstructionStreamPrint(std::ostream& os) {
PrintHeader(os, "InstructionStream");
os << "\n - code: " << Brief(code(kAcquireLoad));
Code the_code = code(kAcquireLoad);
os << "\n - code: " << Brief(the_code);
if (is_builtin()) {
os << "\n - builtin_id: " << Builtins::name(builtin_id());
}
os << "\n";
#ifdef ENABLE_DISASSEMBLER
Disassemble(nullptr, os, GetIsolate());
the_code.Disassemble(nullptr, os, GetIsolate());
#endif
}

View File

@ -598,7 +598,7 @@ void StackFrame::IteratePc(RootVisitor* v, Address* pc_address,
const Address old_pc = ReadPC(pc_address);
DCHECK(isolate_->heap()->GcSafeInstructionStreamContains(unsafe_istream,
old_pc));
const uintptr_t pc_offset = old_pc - unsafe_istream.raw_instruction_start();
const uintptr_t pc_offset = old_pc - unsafe_istream.instruction_start();
// Visit the InstructionStream.
Object visited_unsafe_istream = unsafe_istream;
@ -608,7 +608,7 @@ void StackFrame::IteratePc(RootVisitor* v, Address* pc_address,
// Take care when accessing unsafe_istream from here on. It may have been
// moved.
unsafe_istream = InstructionStream::unchecked_cast(visited_unsafe_istream);
const Address pc = unsafe_istream.raw_instruction_start() + pc_offset;
const Address pc = unsafe_istream.instruction_start() + pc_offset;
// TODO(v8:10026): avoid replacing a signed pointer.
PointerAuthentication::ReplacePC(pc_address, pc, kSystemPointerSize);
if (V8_EMBEDDED_CONSTANT_POOL_BOOL && constant_pool_address != nullptr) {

View File

@ -1995,7 +1995,8 @@ Object Isolate::UnwindAndFindHandler() {
// Jump directly to the optimized frames return, to immediately fall
// into the deoptimizer.
int offset = code.GetOffsetFromInstructionStart(this, frame->pc());
const int offset =
static_cast<int>(frame->pc() - code.instruction_start());
// Compute the stack pointer from the frame pointer. This ensures that
// argument slots on the stack are dropped as returning would.
@ -2003,9 +2004,9 @@ Object Isolate::UnwindAndFindHandler() {
Address return_sp = frame->fp() +
StandardFrameConstants::kFixedFrameSizeAboveFp -
code.stack_slots() * kSystemPointerSize;
return FoundHandler(Context(), code.InstructionStart(this, frame->pc()),
offset, code.constant_pool(), return_sp,
frame->fp(), visited_frames);
return FoundHandler(Context(), code.instruction_start(), offset,
code.constant_pool(), return_sp, frame->fp(),
visited_frames);
}
DCHECK(!frame->is_maglev());
@ -2040,7 +2041,7 @@ Object Isolate::UnwindAndFindHandler() {
thread_local_top()->handler_ = handler->next_address();
InstructionStream code = frame->LookupCode().instruction_stream();
HandlerTable table(code);
Address instruction_start = code.InstructionStart(this, frame->pc());
Address instruction_start = code.instruction_start();
int return_offset = static_cast<int>(frame->pc() - instruction_start);
int handler_offset = table.LookupReturn(return_offset);
DCHECK_NE(-1, handler_offset);
@ -2187,7 +2188,7 @@ Object Isolate::UnwindAndFindHandler() {
// Patch the context register directly on the frame, so that we don't
// need to have a context read + write in the baseline code.
sp_frame->PatchContext(context);
return FoundHandler(Context(), code.InstructionStart(), pc_offset,
return FoundHandler(Context(), code.instruction_start(), pc_offset,
code.constant_pool(), return_sp, sp_frame->fp(),
visited_frames);
} else {

View File

@ -115,7 +115,7 @@ void FullEvacuationVerifier::VerifyCodePointer(CodeObjectSlot slot) {
void FullEvacuationVerifier::VisitCodeTarget(InstructionStream host,
RelocInfo* rinfo) {
InstructionStream target =
InstructionStream::GetCodeFromTargetAddress(rinfo->target_address());
InstructionStream::FromTargetAddress(rinfo->target_address());
VerifyHeapObjectImpl(target);
}
void FullEvacuationVerifier::VisitEmbeddedPointer(InstructionStream host,
@ -161,7 +161,7 @@ void YoungGenerationEvacuationVerifier::VerifyCodePointer(CodeObjectSlot slot) {
void YoungGenerationEvacuationVerifier::VisitCodeTarget(InstructionStream host,
RelocInfo* rinfo) {
InstructionStream target =
InstructionStream::GetCodeFromTargetAddress(rinfo->target_address());
InstructionStream::FromTargetAddress(rinfo->target_address());
VerifyHeapObjectImpl(target);
}
void YoungGenerationEvacuationVerifier::VisitEmbeddedPointer(

View File

@ -155,8 +155,8 @@ MaybeHandle<Code> Factory::CodeBuilder::BuildInternal(
InstructionStream raw_istream = *instruction_stream;
DisallowGarbageCollection no_gc;
raw_istream.set_raw_instruction_size(code_desc_.instruction_size());
raw_istream.set_raw_metadata_size(code_desc_.metadata_size());
raw_istream.set_instruction_size(code_desc_.instruction_size());
raw_istream.set_metadata_size(code_desc_.metadata_size());
raw_istream.set_relocation_info(*reloc_info);
raw_istream.initialize_flags(kind_, is_turbofanned_, stack_slots_);
raw_istream.set_builtin_id(builtin_);
@ -236,7 +236,7 @@ MaybeHandle<Code> Factory::CodeBuilder::BuildInternal(
if (V8_UNLIKELY(profiler_data_ && v8_flags.turbo_profiling_verbose)) {
#ifdef ENABLE_DISASSEMBLER
std::ostringstream os;
instruction_stream->Disassemble(nullptr, os, isolate_);
code->Disassemble(nullptr, os, isolate_);
if (!on_heap_profiler_data.is_null()) {
Handle<String> disassembly =
isolate_->factory()->NewStringFromAsciiChecked(os.str().c_str(),

View File

@ -167,7 +167,7 @@ void VerifyPointersVisitor::VerifyPointers(HeapObject host,
void VerifyPointersVisitor::VisitCodeTarget(InstructionStream host,
RelocInfo* rinfo) {
InstructionStream target =
InstructionStream::GetCodeFromTargetAddress(rinfo->target_address());
InstructionStream::FromTargetAddress(rinfo->target_address());
VerifyHeapObjectImpl(target);
}
@ -493,7 +493,7 @@ class SlotVerifyingVisitor : public ObjectVisitorWithCageBases {
void VisitCodeTarget(InstructionStream host, RelocInfo* rinfo) override {
Object target =
InstructionStream::GetCodeFromTargetAddress(rinfo->target_address());
InstructionStream::FromTargetAddress(rinfo->target_address());
if (ShouldHaveBeenRecorded(host, MaybeObject::FromObject(target))) {
CHECK(InTypedSet(SlotType::kCodeEntry, rinfo->pc()) ||
(rinfo->IsInConstantPool() &&

View File

@ -6309,7 +6309,7 @@ class UnreachableObjectsFilter : public HeapObjectsFilter {
void VisitCodeTarget(InstructionStream host, RelocInfo* rinfo) final {
InstructionStream target =
InstructionStream::GetCodeFromTargetAddress(rinfo->target_address());
InstructionStream::FromTargetAddress(rinfo->target_address());
MarkHeapObject(target);
}
void VisitEmbeddedPointer(InstructionStream host, RelocInfo* rinfo) final {

View File

@ -273,7 +273,7 @@ class FullMarkingVerifier : public MarkingVerifier {
void VisitCodeTarget(InstructionStream host, RelocInfo* rinfo) override {
InstructionStream target =
InstructionStream::GetCodeFromTargetAddress(rinfo->target_address());
InstructionStream::FromTargetAddress(rinfo->target_address());
VerifyHeapObjectImpl(target);
}
@ -1188,7 +1188,7 @@ class MarkCompactCollector::CustomRootBodyMarkingVisitor final
void VisitCodeTarget(InstructionStream host, RelocInfo* rinfo) override {
InstructionStream target =
InstructionStream::GetCodeFromTargetAddress(rinfo->target_address());
InstructionStream::FromTargetAddress(rinfo->target_address());
MarkObject(host, target);
}
@ -1243,7 +1243,7 @@ class MarkCompactCollector::ClientCustomRootBodyMarkingVisitor final
void VisitCodeTarget(InstructionStream host, RelocInfo* rinfo) override {
InstructionStream target =
InstructionStream::GetCodeFromTargetAddress(rinfo->target_address());
InstructionStream::FromTargetAddress(rinfo->target_address());
MarkObject(host, target);
}
@ -1572,7 +1572,7 @@ class RecordMigratedSlotVisitor : public ObjectVisitorWithCageBases {
DCHECK_EQ(host, rinfo->host());
DCHECK(RelocInfo::IsCodeTargetMode(rinfo->rmode()));
InstructionStream target =
InstructionStream::GetCodeFromTargetAddress(rinfo->target_address());
InstructionStream::FromTargetAddress(rinfo->target_address());
// The target is always in old space, we don't have to record the slot in
// the old-to-new remembered set.
DCHECK(!Heap::InYoungGeneration(target));
@ -5657,7 +5657,7 @@ class YoungGenerationMarkingVerifier : public MarkingVerifier {
void VisitCodeTarget(InstructionStream host, RelocInfo* rinfo) override {
InstructionStream target =
InstructionStream::GetCodeFromTargetAddress(rinfo->target_address());
InstructionStream::FromTargetAddress(rinfo->target_address());
VerifyHeapObjectImpl(target);
}
void VisitEmbeddedPointer(InstructionStream host, RelocInfo* rinfo) override {

View File

@ -135,7 +135,7 @@ void MarkingVisitorBase<ConcreteVisitor, MarkingState>::VisitCodeTarget(
InstructionStream host, RelocInfo* rinfo) {
DCHECK(RelocInfo::IsCodeTargetMode(rinfo->rmode()));
InstructionStream target =
InstructionStream::GetCodeFromTargetAddress(rinfo->target_address());
InstructionStream::FromTargetAddress(rinfo->target_address());
if (!ShouldMarkObject(target)) return;
MarkObject(host, target);

View File

@ -64,11 +64,10 @@ HeapObject UpdateTypedSlotHelper::GetTargetObject(Heap* heap,
switch (slot_type) {
case SlotType::kCodeEntry: {
RelocInfo rinfo(addr, RelocInfo::CODE_TARGET, 0, InstructionStream());
return InstructionStream::GetCodeFromTargetAddress(
rinfo.target_address());
return InstructionStream::FromTargetAddress(rinfo.target_address());
}
case SlotType::kConstPoolCodeEntry: {
return InstructionStream::GetObjectFromEntryAddress(addr);
return InstructionStream::FromEntryAddress(addr);
}
case SlotType::kEmbeddedObjectCompressed: {
RelocInfo rinfo(addr, RelocInfo::COMPRESSED_EMBEDDED_OBJECT, 0,

View File

@ -323,8 +323,7 @@ class UpdateTypedSlotHelper {
template <typename Callback>
static SlotCallbackResult UpdateCodeEntry(Address entry_address,
Callback callback) {
InstructionStream code =
InstructionStream::GetObjectFromEntryAddress(entry_address);
InstructionStream code = InstructionStream::FromEntryAddress(entry_address);
InstructionStream old_code = code;
SlotCallbackResult result = callback(FullMaybeObjectSlot(&code));
DCHECK(!HasWeakHeapObjectTag(code));
@ -341,13 +340,13 @@ class UpdateTypedSlotHelper {
Callback callback) {
DCHECK(RelocInfo::IsCodeTargetMode(rinfo->rmode()));
InstructionStream old_target =
InstructionStream::GetCodeFromTargetAddress(rinfo->target_address());
InstructionStream::FromTargetAddress(rinfo->target_address());
InstructionStream new_target = old_target;
SlotCallbackResult result = callback(FullMaybeObjectSlot(&new_target));
DCHECK(!HasWeakHeapObjectTag(new_target));
if (new_target != old_target) {
rinfo->set_target_address(
InstructionStream::cast(new_target).raw_instruction_start());
InstructionStream::cast(new_target).instruction_start());
}
return result;
}

View File

@ -523,7 +523,7 @@ void ScavengeVisitor::VisitCodePointer(HeapObject host, CodeObjectSlot slot) {
void ScavengeVisitor::VisitCodeTarget(InstructionStream host,
RelocInfo* rinfo) {
InstructionStream target =
InstructionStream::GetCodeFromTargetAddress(rinfo->target_address());
InstructionStream::FromTargetAddress(rinfo->target_address());
#ifdef DEBUG
InstructionStream old_target = target;
#endif

View File

@ -72,7 +72,7 @@ class IterateAndScavengePromotedObjectsVisitor final : public ObjectVisitor {
V8_INLINE void VisitCodeTarget(InstructionStream host,
RelocInfo* rinfo) final {
InstructionStream target =
InstructionStream::GetCodeFromTargetAddress(rinfo->target_address());
InstructionStream::FromTargetAddress(rinfo->target_address());
HandleSlot(host, FullHeapObjectSlot(&target), target);
}
V8_INLINE void VisitEmbeddedPointer(InstructionStream host,

View File

@ -610,8 +610,8 @@ void InitializeCodeEvent(Isolate* isolate, CodeEvent* event,
void ExternalLogEventListener::CodeMoveEvent(InstructionStream from,
InstructionStream to) {
CodeEvent code_event;
InitializeCodeEvent(isolate_, &code_event, from.InstructionStart(),
to.InstructionStart(), to.InstructionSize());
InitializeCodeEvent(isolate_, &code_event, from.instruction_start(),
to.instruction_start(), to.instruction_size());
code_event_handler_->Handle(reinterpret_cast<v8::CodeEvent*>(&code_event));
}
@ -759,8 +759,8 @@ void LowLevelLogger::LogRecordedBuffer(const wasm::WasmCode* code,
void LowLevelLogger::CodeMoveEvent(InstructionStream from,
InstructionStream to) {
CodeMoveStruct event;
event.from_address = from.InstructionStart();
event.to_address = to.InstructionStart();
event.from_address = from.instruction_start();
event.to_address = to.instruction_start();
LogWriteStruct(event);
}
@ -898,9 +898,9 @@ void JitLogger::CodeMoveEvent(InstructionStream from, InstructionStream to) {
JitCodeEvent event;
event.type = JitCodeEvent::CODE_MOVED;
event.code_type = JitCodeEvent::JIT_CODE;
event.code_start = reinterpret_cast<void*>(from.InstructionStart());
event.code_len = from.InstructionSize();
event.new_code_start = reinterpret_cast<void*>(to.InstructionStart());
event.code_start = reinterpret_cast<void*>(from.instruction_start());
event.code_len = from.instruction_size();
event.new_code_start = reinterpret_cast<void*>(to.instruction_start());
event.isolate = reinterpret_cast<v8::Isolate*>(isolate_);
code_event_handler_(&event);
@ -1577,8 +1577,8 @@ void V8FileLogger::RegExpCodeCreateEvent(Handle<AbstractCode> code,
void V8FileLogger::CodeMoveEvent(InstructionStream from, InstructionStream to) {
if (!is_listening_to_code_events()) return;
MoveEventInternal(Event::kCodeMove, from.InstructionStart(),
to.InstructionStart());
MoveEventInternal(Event::kCodeMove, from.instruction_start(),
to.instruction_start());
}
void V8FileLogger::BytecodeMoveEvent(BytecodeArray from, BytecodeArray to) {
@ -1613,7 +1613,7 @@ void V8FileLogger::ProcessDeoptEvent(Handle<InstructionStream> code,
const char* reason) {
MSG_BUILDER();
msg << Event::kCodeDeopt << kNext << Time() << kNext << code->CodeSize()
<< kNext << reinterpret_cast<void*>(code->InstructionStart());
<< kNext << reinterpret_cast<void*>(code->instruction_start());
std::ostringstream deopt_location;
int inlining_id = -1;

View File

@ -219,8 +219,8 @@ BytecodeArray AbstractCode::GetBytecodeArray() {
OBJECT_CONSTRUCTORS_IMPL(InstructionStream, HeapObject)
NEVER_READ_ONLY_SPACE_IMPL(InstructionStream)
INT_ACCESSORS(InstructionStream, raw_instruction_size, kInstructionSizeOffset)
INT_ACCESSORS(InstructionStream, raw_metadata_size, kMetadataSizeOffset)
INT_ACCESSORS(InstructionStream, instruction_size, kInstructionSizeOffset)
INT_ACCESSORS(InstructionStream, metadata_size, kMetadataSizeOffset)
INT_ACCESSORS(InstructionStream, handler_table_offset,
kHandlerTableOffsetOffset)
INT_ACCESSORS(InstructionStream, code_comments_offset,
@ -396,16 +396,16 @@ void InstructionStream::WipeOutHeader() {
}
void InstructionStream::clear_padding() {
// Clear the padding between the header and `raw_body_start`.
// Clear the padding between the header and `body_start`.
if (FIELD_SIZE(kOptionalPaddingOffset) != 0) {
memset(reinterpret_cast<void*>(address() + kOptionalPaddingOffset), 0,
FIELD_SIZE(kOptionalPaddingOffset));
}
// Clear the padding after `raw_body_end`.
// Clear the padding after `body_end`.
size_t trailing_padding_size =
CodeSize() - InstructionStream::kHeaderSize - raw_body_size();
memset(reinterpret_cast<void*>(raw_body_end()), 0, trailing_padding_size);
CodeSize() - InstructionStream::kHeaderSize - body_size();
memset(reinterpret_cast<void*>(body_end()), 0, trailing_padding_size);
}
ByteArray Code::SourcePositionTable(PtrComprCageBase cage_base,
@ -426,61 +426,38 @@ ByteArray InstructionStream::SourcePositionTable(PtrComprCageBase cage_base,
return source_position_table(cage_base);
}
Address InstructionStream::raw_body_start() const {
return raw_instruction_start();
Address InstructionStream::body_start() const { return instruction_start(); }
Address InstructionStream::body_end() const {
return body_start() + body_size();
}
Address InstructionStream::raw_body_end() const {
return raw_body_start() + raw_body_size();
}
int InstructionStream::raw_body_size() const {
return raw_instruction_size() + raw_metadata_size();
}
// TODO(jgruber): Remove this.
int InstructionStream::InstructionSize() const {
return raw_instruction_size();
int InstructionStream::body_size() const {
return instruction_size() + metadata_size();
}
int Code::InstructionSize() const {
return V8_LIKELY(has_instruction_stream())
? instruction_stream().raw_instruction_size()
: i::OffHeapInstructionSize(*this, builtin_id());
? instruction_stream().instruction_size()
: OffHeapInstructionSize();
}
Address InstructionStream::raw_instruction_start() const {
Address InstructionStream::instruction_start() const {
return field_address(kHeaderSize);
}
// TODO(jgruber): Remove this.
Address InstructionStream::InstructionStart() const {
return raw_instruction_start();
}
Address InstructionStream::raw_instruction_end() const {
return raw_instruction_start() + raw_instruction_size();
}
// TODO(jgruber): Remove this.
Address InstructionStream::InstructionEnd() const {
return raw_instruction_end();
Address InstructionStream::instruction_end() const {
return instruction_start() + instruction_size();
}
Address Code::InstructionEnd() const {
return V8_LIKELY(has_instruction_stream())
? instruction_stream().raw_instruction_end()
: i::OffHeapInstructionEnd(*this, builtin_id());
? instruction_stream().instruction_end()
: OffHeapInstructionEnd();
}
Address InstructionStream::raw_metadata_start() const {
return raw_instruction_start() + raw_instruction_size();
}
// TODO(jgruber): Remove this.
Address InstructionStream::InstructionStart(Isolate* isolate,
Address pc) const {
return raw_instruction_start();
Address InstructionStream::metadata_start() const {
return instruction_start() + instruction_size();
}
Address Code::InstructionStart(Isolate* isolate, Address pc) const {
@ -489,25 +466,12 @@ Address Code::InstructionStart(Isolate* isolate, Address pc) const {
: OffHeapInstructionStart(isolate, pc);
}
// TODO(jgruber): Remove this.
Address InstructionStream::InstructionEnd(Isolate* isolate, Address pc) const {
return raw_instruction_end();
}
Address Code::InstructionEnd(Isolate* isolate, Address pc) const {
return V8_LIKELY(has_instruction_stream())
? raw_instruction_end()
: OffHeapInstructionEnd(isolate, pc);
}
int InstructionStream::GetOffsetFromInstructionStart(Isolate* isolate,
Address pc) const {
Address instruction_start = InstructionStart(isolate, pc);
Address offset = pc - instruction_start;
DCHECK_LE(offset, InstructionSize());
return static_cast<int>(offset);
}
int Code::GetOffsetFromInstructionStart(Isolate* isolate, Address pc) const {
Address instruction_start = InstructionStart(isolate, pc);
Address offset = pc - instruction_start;
@ -515,13 +479,10 @@ int Code::GetOffsetFromInstructionStart(Isolate* isolate, Address pc) const {
return static_cast<int>(offset);
}
Address InstructionStream::raw_metadata_end() const {
return raw_metadata_start() + raw_metadata_size();
Address InstructionStream::metadata_end() const {
return metadata_start() + metadata_size();
}
// TODO(jgruber): Remove this.
int InstructionStream::MetadataSize() const { return raw_metadata_size(); }
DEF_GETTER(InstructionStream, SizeIncludingMetadata, int) {
int size = CodeSize();
size += relocation_info(cage_base).Size();
@ -531,13 +492,8 @@ DEF_GETTER(InstructionStream, SizeIncludingMetadata, int) {
return size;
}
Address InstructionStream::raw_safepoint_table_address() const {
return raw_metadata_start() + safepoint_table_offset();
}
// TODO(jgruber): Remove this.
Address InstructionStream::SafepointTableAddress() const {
return raw_safepoint_table_address();
Address InstructionStream::safepoint_table_address() const {
return metadata_start() + safepoint_table_offset();
}
int InstructionStream::safepoint_table_size() const {
@ -551,8 +507,8 @@ bool InstructionStream::has_safepoint_table() const {
Address Code::SafepointTableAddress() const {
return V8_LIKELY(has_instruction_stream())
? instruction_stream().raw_safepoint_table_address()
: OffHeapSafepointTableAddress(*this, builtin_id());
? instruction_stream().safepoint_table_address()
: OffHeapSafepointTableAddress();
}
Address GcSafeCode::SafepointTableAddress() const {
@ -560,25 +516,20 @@ Address GcSafeCode::SafepointTableAddress() const {
return V8_LIKELY(has_instruction_stream())
? InstructionStream::unchecked_cast(
unsafe_this.raw_instruction_stream(kRelaxedLoad))
.raw_safepoint_table_address()
: OffHeapSafepointTableAddress(unsafe_this, builtin_id());
.safepoint_table_address()
: unsafe_this.OffHeapSafepointTableAddress();
}
int Code::safepoint_table_size() const {
return V8_LIKELY(has_instruction_stream())
? instruction_stream().safepoint_table_size()
: OffHeapSafepointTableSize(*this, builtin_id());
: OffHeapSafepointTableSize();
}
bool Code::has_safepoint_table() const { return safepoint_table_size() > 0; }
Address InstructionStream::raw_handler_table_address() const {
return raw_metadata_start() + handler_table_offset();
}
// TODO(jgruber): Remove this.
Address InstructionStream::HandlerTableAddress() const {
return raw_handler_table_address();
Address InstructionStream::handler_table_address() const {
return metadata_start() + handler_table_offset();
}
int InstructionStream::handler_table_size() const {
@ -592,14 +543,14 @@ bool InstructionStream::has_handler_table() const {
Address Code::HandlerTableAddress() const {
return V8_LIKELY(has_instruction_stream())
? instruction_stream().raw_handler_table_address()
: OffHeapHandlerTableAddress(*this, builtin_id());
? instruction_stream().handler_table_address()
: OffHeapHandlerTableAddress();
}
int Code::handler_table_size() const {
return V8_LIKELY(has_instruction_stream())
? instruction_stream().handler_table_size()
: OffHeapHandlerTableSize(*this, builtin_id());
: OffHeapHandlerTableSize();
}
bool Code::has_handler_table() const { return handler_table_size() > 0; }
@ -621,7 +572,7 @@ bool InstructionStream::has_constant_pool() const {
int Code::constant_pool_size() const {
return V8_LIKELY(has_instruction_stream())
? instruction_stream().constant_pool_size()
: OffHeapConstantPoolSize(*this, builtin_id());
: OffHeapConstantPoolSize();
}
bool Code::has_constant_pool() const { return constant_pool_size() > 0; }
@ -662,7 +613,7 @@ int Code::relocation_size() const {
: 0;
}
Address InstructionStream::entry() const { return raw_instruction_start(); }
Address InstructionStream::entry() const { return instruction_start(); }
bool InstructionStream::contains(Isolate* isolate, Address inner_pointer) {
return (address() <= inner_pointer) &&
@ -684,7 +635,7 @@ void InstructionStream::CopyRelocInfoToByteArray(ByteArray dest,
static_cast<size_t>(desc.reloc_size));
}
int InstructionStream::CodeSize() const { return SizeFor(raw_body_size()); }
int InstructionStream::CodeSize() const { return SizeFor(body_size()); }
DEF_GETTER(InstructionStream, Size, int) { return CodeSize(); }
@ -702,7 +653,7 @@ int InstructionStream::GetBytecodeOffsetForBaselinePC(Address baseline_pc,
CHECK_EQ(kind(), CodeKind::BASELINE);
baseline::BytecodeOffsetIterator offset_iterator(
ByteArray::cast(bytecode_offset_table()), bytecodes);
Address pc = baseline_pc - InstructionStart();
Address pc = baseline_pc - instruction_start();
offset_iterator.AdvanceToPCOffset(pc);
return offset_iterator.current_bytecode_offset();
}
@ -782,7 +733,6 @@ inline bool InstructionStream::is_baseline_leave_frame_builtin() const {
return builtin_id() == Builtin::kBaselineLeaveFrame;
}
// Note, must be in sync with InstructionStream::checks_tiering_state().
inline bool Code::checks_tiering_state() const {
bool checks_state = (builtin_id() == Builtin::kCompileLazy ||
builtin_id() == Builtin::kInterpreterEntryTrampoline ||
@ -791,15 +741,6 @@ inline bool Code::checks_tiering_state() const {
(CodeKindCanDeoptimize(kind()) && marked_for_deoptimization());
}
// Note, must be in sync with Code::checks_tiering_state().
inline bool InstructionStream::checks_tiering_state() const {
bool checks_state = (builtin_id() == Builtin::kCompileLazy ||
builtin_id() == Builtin::kInterpreterEntryTrampoline ||
CodeKindCanTierUp(kind()));
return checks_state ||
(CodeKindCanDeoptimize(kind()) && marked_for_deoptimization());
}
inline constexpr bool CodeKindHasTaggedOutgoingParams(CodeKind kind) {
return kind != CodeKind::JS_TO_WASM_FUNCTION &&
kind != CodeKind::C_WASM_ENTRY && kind != CodeKind::WASM_FUNCTION;
@ -884,12 +825,6 @@ inline bool InstructionStream::is_promise_rejection() const {
return container.is_promise_rejection();
}
inline void InstructionStream::set_is_promise_rejection(bool value) {
DCHECK_EQ(kind(), CodeKind::BUILTIN);
Code container = code(kAcquireLoad);
container.set_is_promise_rejection(value);
}
inline HandlerTable::CatchPrediction
InstructionStream::GetBuiltinCatchPrediction() const {
if (is_promise_rejection()) return HandlerTable::PROMISE;
@ -955,7 +890,7 @@ int InstructionStream::stack_slots() const {
int Code::stack_slots() const {
return V8_LIKELY(has_instruction_stream())
? instruction_stream().stack_slots()
: OffHeapStackSlots(*this, builtin_id());
: OffHeapStackSlots();
}
int GcSafeCode::stack_slots() const {
@ -964,7 +899,7 @@ int GcSafeCode::stack_slots() const {
? InstructionStream::unchecked_cast(
unsafe_this.raw_instruction_stream(kRelaxedLoad))
.stack_slots()
: OffHeapStackSlots(unsafe_this, builtin_id());
: unsafe_this.OffHeapStackSlots();
}
bool Code::marked_for_deoptimization() const {
@ -1029,34 +964,26 @@ void InstructionStream::set_constant_pool_offset(int value) {
// Redirection needed since the field doesn't exist in this case.
return;
}
DCHECK_LE(value, MetadataSize());
DCHECK_LE(value, metadata_size());
WriteField<int>(kConstantPoolOffsetOffset, value);
}
Address InstructionStream::raw_constant_pool() const {
if (!has_constant_pool()) return kNullAddress;
return raw_metadata_start() + constant_pool_offset();
}
Address InstructionStream::constant_pool() const {
if (!has_constant_pool()) return kNullAddress;
return raw_constant_pool();
return metadata_start() + constant_pool_offset();
}
Address Code::constant_pool() const {
if (!has_constant_pool()) return kNullAddress;
return V8_LIKELY(has_instruction_stream())
? instruction_stream().raw_constant_pool()
: OffHeapConstantPoolAddress(*this, builtin_id());
? instruction_stream().constant_pool()
: OffHeapConstantPoolAddress();
}
Address InstructionStream::raw_code_comments() const {
return raw_metadata_start() + code_comments_offset();
Address InstructionStream::code_comments() const {
return metadata_start() + code_comments_offset();
}
// TODO(jgruber): Remove this.
Address InstructionStream::code_comments() const { return raw_code_comments(); }
int InstructionStream::code_comments_size() const {
DCHECK_GE(unwinding_info_offset() - code_comments_offset(), 0);
return unwinding_info_offset() - code_comments_offset();
@ -1069,30 +996,22 @@ bool InstructionStream::has_code_comments() const {
Address Code::code_comments() const {
return V8_LIKELY(has_instruction_stream())
? instruction_stream().code_comments()
: OffHeapCodeCommentsAddress(*this, builtin_id());
: OffHeapCodeCommentsAddress();
}
int Code::code_comments_size() const {
return V8_LIKELY(has_instruction_stream())
? instruction_stream().code_comments_size()
: OffHeapCodeCommentsSize(*this, builtin_id());
: OffHeapCodeCommentsSize();
}
bool Code::has_code_comments() const { return code_comments_size() > 0; }
Address InstructionStream::raw_unwinding_info_start() const {
return raw_metadata_start() + unwinding_info_offset();
}
// TODO(jgruber): Remove this.
Address InstructionStream::unwinding_info_start() const {
return raw_unwinding_info_start();
return metadata_start() + unwinding_info_offset();
}
// TODO(jgruber): Remove this.
Address InstructionStream::unwinding_info_end() const {
return raw_metadata_end();
}
Address InstructionStream::unwinding_info_end() const { return metadata_end(); }
int InstructionStream::unwinding_info_size() const {
DCHECK_GE(unwinding_info_end(), unwinding_info_start());
@ -1105,20 +1024,20 @@ bool InstructionStream::has_unwinding_info() const {
Address Code::unwinding_info_start() const {
return V8_LIKELY(has_instruction_stream())
? instruction_stream().raw_unwinding_info_start()
: OffHeapUnwindingInfoAddress(*this, builtin_id());
? instruction_stream().unwinding_info_start()
: OffHeapUnwindingInfoAddress();
}
Address Code::unwinding_info_end() const {
return V8_LIKELY(has_instruction_stream())
? instruction_stream().raw_metadata_end()
: OffHeapMetadataEnd(*this, builtin_id());
? instruction_stream().metadata_end()
: OffHeapMetadataEnd();
}
int Code::unwinding_info_size() const {
return V8_LIKELY(has_instruction_stream())
? instruction_stream().unwinding_info_size()
: OffHeapUnwindingInfoSize(*this, builtin_id());
: OffHeapUnwindingInfoSize();
DCHECK_GE(unwinding_info_end(), unwinding_info_start());
return static_cast<int>(unwinding_info_end() - unwinding_info_start());
@ -1126,7 +1045,8 @@ int Code::unwinding_info_size() const {
bool Code::has_unwinding_info() const { return unwinding_info_size() > 0; }
InstructionStream InstructionStream::GetCodeFromTargetAddress(Address address) {
// static
InstructionStream InstructionStream::FromTargetAddress(Address address) {
{
// TODO(jgruber,v8:6666): Support embedded builtins here. We'd need to pass
// in the current isolate.
@ -1138,18 +1058,19 @@ InstructionStream InstructionStream::GetCodeFromTargetAddress(Address address) {
HeapObject code =
HeapObject::FromAddress(address - InstructionStream::kHeaderSize);
// Unchecked cast because we can't rely on the map currently
// not being a forwarding pointer.
// Unchecked cast because we can't rely on the map currently not being a
// forwarding pointer.
return InstructionStream::unchecked_cast(code);
}
InstructionStream InstructionStream::GetObjectFromEntryAddress(
// static
InstructionStream InstructionStream::FromEntryAddress(
Address location_of_address) {
Address code_entry = base::Memory<Address>(location_of_address);
HeapObject code =
HeapObject::FromAddress(code_entry - InstructionStream::kHeaderSize);
// Unchecked cast because we can't rely on the map currently
// not being a forwarding pointer.
// Unchecked cast because we can't rely on the map currently not being a
// forwarding pointer.
return InstructionStream::unchecked_cast(code);
}
@ -1265,7 +1186,7 @@ void Code::SetInstructionStreamAndEntryPoint(Isolate* isolate_for_sandbox,
InstructionStream code,
WriteBarrierMode mode) {
set_raw_instruction_stream(code, mode);
set_code_entry_point(isolate_for_sandbox, code.InstructionStart());
set_code_entry_point(isolate_for_sandbox, code.instruction_start());
}
void Code::SetEntryPointForOffHeapBuiltin(Isolate* isolate_for_sandbox,
@ -1277,7 +1198,7 @@ void Code::SetEntryPointForOffHeapBuiltin(Isolate* isolate_for_sandbox,
void Code::UpdateCodeEntryPoint(Isolate* isolate_for_sandbox,
InstructionStream code) {
DCHECK_EQ(raw_instruction_stream(), code);
set_code_entry_point(isolate_for_sandbox, code.InstructionStart());
set_code_entry_point(isolate_for_sandbox, code.instruction_start());
}
Address Code::InstructionStart() const { return code_entry_point(); }
@ -1286,14 +1207,12 @@ Address Code::raw_instruction_start() const { return code_entry_point(); }
Address Code::raw_instruction_end() const {
DCHECK(has_instruction_stream());
return InstructionStream::unchecked_cast(raw_instruction_stream())
.raw_instruction_end();
.instruction_end();
}
int Code::raw_instruction_size() const {
return instruction_stream().raw_instruction_size();
}
Address Code::raw_body_size() const {
return instruction_stream().raw_body_size();
return instruction_stream().instruction_size();
}
Address Code::raw_body_size() const { return instruction_stream().body_size(); }
Address Code::entry() const { return code_entry_point(); }
@ -1353,25 +1272,26 @@ inline bool Code::is_baseline_leave_frame_builtin() const {
// InstructionStream object.
//
#define DEF_PRIMITIVE_FORWARDING_CDC_GETTER(name, type) \
#define DEF_PRIMITIVE_FORWARDING_CODE_GETTER(name, type) \
type Code::name() const { return FromCode(*this).name(); }
#define DEF_FORWARDING_CDC_GETTER(name, type, result_if_no_instruction_stream) \
DEF_GETTER(Code, name, type) { \
if (!has_instruction_stream()) { \
return GetReadOnlyRoots().result_if_no_instruction_stream(); \
} \
return FromCode(*this).name(cage_base); \
#define DEF_FORWARDING_CODE_GETTER(name, type, \
result_if_no_instruction_stream) \
DEF_GETTER(Code, name, type) { \
if (!has_instruction_stream()) { \
return GetReadOnlyRoots().result_if_no_instruction_stream(); \
} \
return FromCode(*this).name(cage_base); \
}
DEF_FORWARDING_CDC_GETTER(deoptimization_data, FixedArray, empty_fixed_array)
DEF_FORWARDING_CDC_GETTER(bytecode_or_interpreter_data, HeapObject,
empty_fixed_array)
DEF_FORWARDING_CDC_GETTER(source_position_table, ByteArray, empty_byte_array)
DEF_FORWARDING_CDC_GETTER(bytecode_offset_table, ByteArray, empty_byte_array)
DEF_FORWARDING_CODE_GETTER(deoptimization_data, FixedArray, empty_fixed_array)
DEF_FORWARDING_CODE_GETTER(bytecode_or_interpreter_data, HeapObject,
empty_fixed_array)
DEF_FORWARDING_CODE_GETTER(source_position_table, ByteArray, empty_byte_array)
DEF_FORWARDING_CODE_GETTER(bytecode_offset_table, ByteArray, empty_byte_array)
#undef DEF_PRIMITIVE_FORWARDING_CDC_GETTER
#undef DEF_FORWARDING_CDC_GETTER
#undef DEF_PRIMITIVE_FORWARDING_CODE_GETTER
#undef DEF_FORWARDING_CODE_GETTER
byte BytecodeArray::get(int index) const {
DCHECK(index >= 0 && index < this->length());

View File

@ -63,91 +63,108 @@ inline EmbeddedData EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(
} // namespace
Address OffHeapInstructionStart(HeapObject code, Builtin builtin) {
Address Code::OffHeapInstructionStart() const {
// TODO(11527): Here and below: pass Isolate as an argument for getting
// the EmbeddedData.
EmbeddedData d = EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(code);
Builtin builtin = builtin_id();
EmbeddedData d = EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(*this);
return d.InstructionStartOfBuiltin(builtin);
}
Address OffHeapInstructionEnd(HeapObject code, Builtin builtin) {
EmbeddedData d = EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(code);
Address Code::OffHeapInstructionEnd() const {
Builtin builtin = builtin_id();
EmbeddedData d = EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(*this);
return d.InstructionStartOfBuiltin(builtin) +
d.InstructionSizeOfBuiltin(builtin);
}
int OffHeapInstructionSize(HeapObject code, Builtin builtin) {
EmbeddedData d = EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(code);
int Code::OffHeapInstructionSize() const {
Builtin builtin = builtin_id();
EmbeddedData d = EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(*this);
return d.InstructionSizeOfBuiltin(builtin);
}
Address OffHeapMetadataStart(HeapObject code, Builtin builtin) {
EmbeddedData d = EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(code);
Address Code::OffHeapMetadataStart() const {
Builtin builtin = builtin_id();
EmbeddedData d = EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(*this);
return d.MetadataStartOfBuiltin(builtin);
}
Address OffHeapMetadataEnd(HeapObject code, Builtin builtin) {
EmbeddedData d = EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(code);
Address Code::OffHeapMetadataEnd() const {
Builtin builtin = builtin_id();
EmbeddedData d = EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(*this);
return d.MetadataStartOfBuiltin(builtin) + d.MetadataSizeOfBuiltin(builtin);
}
int OffHeapMetadataSize(HeapObject code, Builtin builtin) {
EmbeddedData d = EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(code);
int Code::OffHeapMetadataSize() const {
Builtin builtin = builtin_id();
EmbeddedData d = EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(*this);
return d.MetadataSizeOfBuiltin(builtin);
}
Address OffHeapSafepointTableAddress(HeapObject code, Builtin builtin) {
EmbeddedData d = EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(code);
Address Code::OffHeapSafepointTableAddress() const {
Builtin builtin = builtin_id();
EmbeddedData d = EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(*this);
return d.SafepointTableStartOf(builtin);
}
int OffHeapSafepointTableSize(HeapObject code, Builtin builtin) {
EmbeddedData d = EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(code);
int Code::OffHeapSafepointTableSize() const {
Builtin builtin = builtin_id();
EmbeddedData d = EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(*this);
return d.SafepointTableSizeOf(builtin);
}
Address OffHeapHandlerTableAddress(HeapObject code, Builtin builtin) {
EmbeddedData d = EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(code);
Address Code::OffHeapHandlerTableAddress() const {
Builtin builtin = builtin_id();
EmbeddedData d = EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(*this);
return d.HandlerTableStartOf(builtin);
}
int OffHeapHandlerTableSize(HeapObject code, Builtin builtin) {
EmbeddedData d = EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(code);
int Code::OffHeapHandlerTableSize() const {
Builtin builtin = builtin_id();
EmbeddedData d = EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(*this);
return d.HandlerTableSizeOf(builtin);
}
Address OffHeapConstantPoolAddress(HeapObject code, Builtin builtin) {
EmbeddedData d = EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(code);
Address Code::OffHeapConstantPoolAddress() const {
Builtin builtin = builtin_id();
EmbeddedData d = EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(*this);
return d.ConstantPoolStartOf(builtin);
}
int OffHeapConstantPoolSize(HeapObject code, Builtin builtin) {
EmbeddedData d = EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(code);
int Code::OffHeapConstantPoolSize() const {
Builtin builtin = builtin_id();
EmbeddedData d = EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(*this);
return d.ConstantPoolSizeOf(builtin);
}
Address OffHeapCodeCommentsAddress(HeapObject code, Builtin builtin) {
EmbeddedData d = EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(code);
Address Code::OffHeapCodeCommentsAddress() const {
Builtin builtin = builtin_id();
EmbeddedData d = EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(*this);
return d.CodeCommentsStartOf(builtin);
}
int OffHeapCodeCommentsSize(HeapObject code, Builtin builtin) {
EmbeddedData d = EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(code);
int Code::OffHeapCodeCommentsSize() const {
Builtin builtin = builtin_id();
EmbeddedData d = EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(*this);
return d.CodeCommentsSizeOf(builtin);
}
Address OffHeapUnwindingInfoAddress(HeapObject code, Builtin builtin) {
EmbeddedData d = EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(code);
Address Code::OffHeapUnwindingInfoAddress() const {
Builtin builtin = builtin_id();
EmbeddedData d = EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(*this);
return d.UnwindingInfoStartOf(builtin);
}
int OffHeapUnwindingInfoSize(HeapObject code, Builtin builtin) {
EmbeddedData d = EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(code);
int Code::OffHeapUnwindingInfoSize() const {
Builtin builtin = builtin_id();
EmbeddedData d = EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(*this);
return d.UnwindingInfoSizeOf(builtin);
}
int OffHeapStackSlots(HeapObject code, Builtin builtin) {
EmbeddedData d = EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(code);
int Code::OffHeapStackSlots() const {
Builtin builtin = builtin_id();
EmbeddedData d = EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(*this);
return d.StackSlotsOf(builtin);
}
@ -169,17 +186,17 @@ void InstructionStream::Relocate(intptr_t delta) {
}
void InstructionStream::FlushICache() const {
FlushInstructionCache(raw_instruction_start(), raw_instruction_size());
FlushInstructionCache(instruction_start(), instruction_size());
}
void InstructionStream::CopyFromNoFlush(ByteArray reloc_info, Heap* heap,
const CodeDesc& desc) {
// Copy code.
static_assert(kOnHeapBodyIsContiguous);
CopyBytes(reinterpret_cast<byte*>(raw_instruction_start()), desc.buffer,
CopyBytes(reinterpret_cast<byte*>(instruction_start()), desc.buffer,
static_cast<size_t>(desc.instr_size));
// TODO(jgruber,v8:11036): Merge with the above.
CopyBytes(reinterpret_cast<byte*>(raw_instruction_start() + desc.instr_size),
CopyBytes(reinterpret_cast<byte*>(instruction_start() + desc.instr_size),
desc.unwinding_info, static_cast<size_t>(desc.unwinding_info_size));
// Copy reloc info.
@ -206,7 +223,7 @@ void InstructionStream::RelocateFromDesc(ByteArray reloc_info, Heap* heap,
Handle<HeapObject> p = it.rinfo()->target_object_handle(origin);
DCHECK(p->IsCode(GetPtrComprCageBaseSlow(*p)));
InstructionStream code = FromCode(Code::cast(*p));
it.rinfo()->set_target_address(code.raw_instruction_start(),
it.rinfo()->set_target_address(code.instruction_start(),
UPDATE_WRITE_BARRIER, SKIP_ICACHE_FLUSH);
} else if (RelocInfo::IsNearBuiltinEntry(mode)) {
// Rewrite builtin IDs to PC-relative offset to the builtin entry point.
@ -218,7 +235,7 @@ void InstructionStream::RelocateFromDesc(ByteArray reloc_info, Heap* heap,
DCHECK_EQ(p, it.rinfo()->target_address());
} else {
intptr_t delta =
raw_instruction_start() - reinterpret_cast<Address>(desc.buffer);
instruction_start() - reinterpret_cast<Address>(desc.buffer);
it.rinfo()->apply(delta);
}
}
@ -298,7 +315,7 @@ int AbstractCode::SourceStatementPosition(PtrComprCageBase cage_base,
bool InstructionStream::CanDeoptAt(Isolate* isolate, Address pc) {
DeoptimizationData deopt_data =
DeoptimizationData::cast(deoptimization_data());
Address code_start_address = InstructionStart(isolate, pc);
Address code_start_address = instruction_start();
for (int i = 0; i < deopt_data.DeoptCount(); i++) {
if (deopt_data.Pc(i).value() == -1) continue;
Address address = code_start_address + deopt_data.Pc(i).value();
@ -346,7 +363,7 @@ bool InstructionStream::IsIsolateIndependent(Isolate* isolate) {
continue;
InstructionStream target =
InstructionStream::GetCodeFromTargetAddress(target_address);
InstructionStream::FromTargetAddress(target_address);
CHECK(target.IsInstructionStream());
if (Builtins::IsIsolateIndependentBuiltin(target.code(kAcquireLoad))) {
continue;
@ -500,10 +517,8 @@ void DeoptimizationData::DeoptimizationDataPrint(std::ostream& os) {
namespace {
template <typename CodeOrInstructionStream>
inline void DisassembleCodeRange(Isolate* isolate, std::ostream& os,
CodeOrInstructionStream code, Address begin,
size_t size, Address current_pc) {
void DisassembleCodeRange(Isolate* isolate, std::ostream& os, Code code,
Address begin, size_t size, Address current_pc) {
Address end = begin + size;
AllowHandleAllocation allow_handles;
DisallowGarbageCollection no_gc;
@ -513,9 +528,8 @@ inline void DisassembleCodeRange(Isolate* isolate, std::ostream& os,
CodeReference(handle(code, isolate)), current_pc);
}
template <typename CodeOrInstructionStream>
void Disassemble(const char* name, std::ostream& os, Isolate* isolate,
CodeOrInstructionStream code, Address current_pc) {
Code code, Address current_pc) {
CodeKind kind = code.kind();
os << "kind = " << CodeKindToString(kind) << "\n";
if (name == nullptr && code.is_builtin()) {
@ -636,11 +650,6 @@ void Disassemble(const char* name, std::ostream& os, Isolate* isolate,
} // namespace
void InstructionStream::Disassemble(const char* name, std::ostream& os,
Isolate* isolate, Address current_pc) {
i::Disassemble(name, os, isolate, *this, current_pc);
}
void Code::Disassemble(const char* name, std::ostream& os, Isolate* isolate,
Address current_pc) {
i::Disassemble(name, os, isolate, *this, current_pc);

View File

@ -46,6 +46,27 @@ class Register;
// write-protected pages within the heap, its header fields need to be
// immutable. Every InstructionStream object has an associated Code object,
// but not every Code object has an InstructionStream (e.g. for builtins).
//
// Embedded builtins consist of on-heap Code objects, with an out-of-line body
// section. Accessors (e.g. InstructionStart), redirect to the off-heap area.
// Metadata table offsets remain relative to MetadataStart(), i.e. they point
// into the off-heap metadata section. The off-heap layout is described in
// detail in the EmbeddedData class, but at a high level one can assume a
// dedicated, out-of-line, instruction and metadata section for each embedded
// builtin:
//
// +--------------------------+ <-- InstructionStart()
// | off-heap instructions |
// | ... |
// +--------------------------+ <-- InstructionEnd()
//
// +--------------------------+ <-- MetadataStart() (MS)
// | off-heap metadata |
// | ... | <-- MS + handler_table_offset()
// | | <-- MS + constant_pool_offset()
// | | <-- MS + code_comments_offset()
// | | <-- MS + unwinding_info_offset()
// +--------------------------+ <-- MetadataEnd()
class Code : public HeapObject {
public:
NEVER_READ_ONLY_SPACE
@ -63,6 +84,11 @@ class Code : public HeapObject {
DECL_PRIMITIVE_ACCESSORS(can_have_weak_objects, bool)
DECL_PRIMITIVE_ACCESSORS(marked_for_deoptimization, bool)
// [is_promise_rejection]: For kind BUILTIN tells whether the
// exception thrown by the code will lead to promise rejection or
// uncaught if both this and is_exception_caught is set.
// Use GetBuiltinCatchPrediction to access this.
DECL_PRIMITIVE_ACCESSORS(is_promise_rejection, bool)
inline HandlerTable::CatchPrediction GetBuiltinCatchPrediction() const;
@ -221,6 +247,7 @@ class Code : public HeapObject {
// raw_instruction_start/end() values.
// TODO(11527): remove these versions once the full solution is ready.
inline Address InstructionStart(Isolate* isolate, Address pc) const;
V8_EXPORT_PRIVATE Address OffHeapInstructionStart() const;
V8_EXPORT_PRIVATE Address OffHeapInstructionStart(Isolate* isolate,
Address pc) const;
inline Address InstructionEnd(Isolate* isolate, Address pc) const;
@ -305,8 +332,26 @@ class Code : public HeapObject {
// InstructionStream object.
DECL_RELAXED_UINT16_ACCESSORS(flags)
V8_EXPORT_PRIVATE Address OffHeapInstructionEnd() const;
V8_EXPORT_PRIVATE int OffHeapInstructionSize() const;
V8_EXPORT_PRIVATE Address OffHeapMetadataStart() const;
V8_EXPORT_PRIVATE Address OffHeapMetadataEnd() const;
V8_EXPORT_PRIVATE int OffHeapMetadataSize() const;
V8_EXPORT_PRIVATE Address OffHeapSafepointTableAddress() const;
V8_EXPORT_PRIVATE int OffHeapSafepointTableSize() const;
V8_EXPORT_PRIVATE Address OffHeapHandlerTableAddress() const;
V8_EXPORT_PRIVATE int OffHeapHandlerTableSize() const;
V8_EXPORT_PRIVATE Address OffHeapConstantPoolAddress() const;
V8_EXPORT_PRIVATE int OffHeapConstantPoolSize() const;
V8_EXPORT_PRIVATE Address OffHeapCodeCommentsAddress() const;
V8_EXPORT_PRIVATE int OffHeapCodeCommentsSize() const;
V8_EXPORT_PRIVATE Address OffHeapUnwindingInfoAddress() const;
V8_EXPORT_PRIVATE int OffHeapUnwindingInfoSize() const;
V8_EXPORT_PRIVATE int OffHeapStackSlots() const;
template <typename IsolateT>
friend class Deserializer;
friend class GcSafeCode; // For OffHeapFoo functions.
friend Factory;
friend FactoryBase<Factory>;
friend FactoryBase<LocalFactory>;
@ -375,8 +420,9 @@ class GcSafeCode : public HeapObject {
class InstructionStream : public HeapObject {
public:
NEVER_READ_ONLY_SPACE
// Opaque data type for encapsulating code flags like kind, inline
// cache state, and arguments count.
// Opaque data type for encapsulating code flags like kind, inline cache
// state, and arguments count.
using Flags = uint32_t;
// All InstructionStream objects have the following layout:
@ -384,53 +430,24 @@ class InstructionStream : public HeapObject {
// +--------------------------+
// | header |
// | padded to code alignment |
// +--------------------------+ <-- raw_body_start()
// | instructions | == raw_instruction_start()
// +--------------------------+ <-- body_start()
// | instructions | == instruction_start()
// | ... |
// | padded to meta alignment | see kMetadataAlignment
// +--------------------------+ <-- raw_instruction_end()
// | metadata | == raw_metadata_start() (MS)
// +--------------------------+ <-- instruction_end()
// | metadata | == metadata_start() (MS)
// | ... |
// | | <-- MS + handler_table_offset()
// | | <-- MS + constant_pool_offset()
// | | <-- MS + code_comments_offset()
// | | <-- MS + unwinding_info_offset()
// | padded to obj alignment |
// +--------------------------+ <-- raw_metadata_end() == raw_body_end()
// +--------------------------+ <-- metadata_end() == body_end()
// | padded to code alignment |
// +--------------------------+
//
// In other words, the variable-size 'body' consists of 'instructions' and
// 'metadata'.
//
// Note the accessor functions below may be prefixed with 'raw'. In this case,
// raw accessors (e.g. raw_instruction_start) always refer to the on-heap
// InstructionStream object, while camel-case accessors (e.g.
// InstructionStart) may refer to an off-heap area in the case of embedded
// builtins.
//
// Embedded builtins are on-heap InstructionStream objects, with an
// out-of-line body section. The on-heap InstructionStream object contains an
// essentially empty body section, while accessors, as mentioned above,
// redirect to the off-heap area. Metadata table offsets remain relative to
// MetadataStart(), i.e. they point into the off-heap metadata section. The
// off-heap layout is described in detail in the EmbeddedData class, but at a
// high level one can assume a dedicated, out-of-line, instruction and
// metadata section for each embedded builtin *in addition* to the on-heap
// InstructionStream object:
//
// +--------------------------+ <-- InstructionStart()
// | off-heap instructions |
// | ... |
// +--------------------------+ <-- InstructionEnd()
//
// +--------------------------+ <-- MetadataStart() (MS)
// | off-heap metadata |
// | ... | <-- MS + handler_table_offset()
// | | <-- MS + constant_pool_offset()
// | | <-- MS + code_comments_offset()
// | | <-- MS + unwinding_info_offset()
// +--------------------------+ <-- MetadataEnd()
// Constants for use in static asserts, stating whether the body is adjacent,
// i.e. instructions and metadata areas are adjacent.
@ -439,51 +456,27 @@ class InstructionStream : public HeapObject {
static constexpr bool kBodyIsContiguous =
kOnHeapBodyIsContiguous && kOffHeapBodyIsContiguous;
inline Address raw_body_start() const;
inline Address raw_body_end() const;
inline int raw_body_size() const;
inline Address body_start() const;
inline Address body_end() const;
inline int body_size() const;
inline Address raw_instruction_start() const;
inline Address InstructionStart() const;
inline Address instruction_start() const;
inline Address instruction_end() const;
inline Address raw_instruction_end() const;
inline Address InstructionEnd() const;
inline int instruction_size() const;
inline void set_instruction_size(int value);
// When builtins un-embedding is enabled for the Isolate
// (see Isolate::is_short_builtin_calls_enabled()) then both embedded and
// un-embedded builtins might be exeuted and thus two kinds of |pc|s might
// appear on the stack.
// Unlike the paremeterless versions of the functions above the below variants
// ensure that the instruction start correspond to the given |pc| value.
// Thus for off-heap trampoline InstructionStream objects the result might be
// the instruction start/end of the embedded code stream or of un-embedded
// one. For normal InstructionStream objects these functions just return the
// raw_instruction_start/end() values.
// TODO(11527): remove these versions once the full solution is ready.
inline Address InstructionStart(Isolate* isolate, Address pc) const;
inline Address InstructionEnd(Isolate* isolate, Address pc) const;
// Computes offset of the |pc| from the instruction start. The |pc| must
// belong to this code.
inline int GetOffsetFromInstructionStart(Isolate* isolate, Address pc) const;
inline int raw_instruction_size() const;
inline void set_raw_instruction_size(int value);
inline int InstructionSize() const;
inline Address raw_metadata_start() const;
inline Address raw_metadata_end() const;
inline int raw_metadata_size() const;
inline void set_raw_metadata_size(int value);
inline int MetadataSize() const;
inline Address metadata_start() const;
inline Address metadata_end() const;
inline int metadata_size() const;
inline void set_metadata_size(int value);
// The metadata section is aligned to this value.
static constexpr int kMetadataAlignment = kIntSize;
// [safepoint_table_offset]: The offset where the safepoint table starts.
inline int safepoint_table_offset() const { return 0; }
inline Address raw_safepoint_table_address() const;
inline Address SafepointTableAddress() const;
inline Address safepoint_table_address() const;
inline int safepoint_table_size() const;
inline bool has_safepoint_table() const;
@ -491,15 +484,13 @@ class InstructionStream : public HeapObject {
// starts.
inline int handler_table_offset() const;
inline void set_handler_table_offset(int offset);
inline Address raw_handler_table_address() const;
inline Address HandlerTableAddress() const;
inline Address handler_table_address() const;
inline int handler_table_size() const;
inline bool has_handler_table() const;
// [constant_pool offset]: Offset of the constant pool.
inline int constant_pool_offset() const;
inline void set_constant_pool_offset(int offset);
inline Address raw_constant_pool() const;
inline Address constant_pool() const;
inline int constant_pool_size() const;
inline bool has_constant_pool() const;
@ -507,7 +498,6 @@ class InstructionStream : public HeapObject {
// [code_comments_offset]: Offset of the code comment section.
inline int code_comments_offset() const;
inline void set_code_comments_offset(int offset);
inline Address raw_code_comments() const;
inline Address code_comments() const;
inline int code_comments_size() const;
inline bool has_code_comments() const;
@ -515,18 +505,11 @@ class InstructionStream : public HeapObject {
// [unwinding_info_offset]: Offset of the unwinding info section.
inline int32_t unwinding_info_offset() const;
inline void set_unwinding_info_offset(int32_t offset);
inline Address raw_unwinding_info_start() const;
inline Address unwinding_info_start() const;
inline Address unwinding_info_end() const;
inline int unwinding_info_size() const;
inline bool has_unwinding_info() const;
#ifdef ENABLE_DISASSEMBLER
V8_EXPORT_PRIVATE void Disassemble(const char* name, std::ostream& os,
Isolate* isolate,
Address current_pc = kNullAddress);
#endif
// [relocation_info]: InstructionStream relocation information
DECL_ACCESSORS(relocation_info, ByteArray)
@ -552,7 +535,7 @@ class InstructionStream : public HeapObject {
inline ByteArray SourcePositionTable(PtrComprCageBase cage_base,
SharedFunctionInfo sfi) const;
// [code]: A container indirection for all mutable fields.
// [code]: The associated Code object.
DECL_RELEASE_ACQUIRE_ACCESSORS(code, Code)
DECL_RELEASE_ACQUIRE_ACCESSORS(raw_code, HeapObject)
@ -567,17 +550,10 @@ class InstructionStream : public HeapObject {
inline bool is_optimized_code() const;
inline bool is_wasm_code() const;
// Testers for interpreter builtins.
inline bool is_interpreter_trampoline_builtin() const;
// Testers for baseline builtins.
inline bool is_baseline_trampoline_builtin() const;
inline bool is_baseline_leave_frame_builtin() const;
// Tells whether the code checks the tiering state in the function's
// feedback vector.
inline bool checks_tiering_state() const;
// Tells whether the outgoing parameters of this code are tagged pointers.
inline bool has_tagged_outgoing_params() const;
@ -628,12 +604,6 @@ class InstructionStream : public HeapObject {
inline bool embedded_objects_cleared() const;
inline void set_embedded_objects_cleared(bool flag);
// [is_promise_rejection]: For kind BUILTIN tells whether the
// exception thrown by the code will lead to promise rejection or
// uncaught if both this and is_exception_caught is set.
// Use GetBuiltinCatchPrediction to access this.
inline void set_is_promise_rejection(bool flag);
// The entire code object including its header is copied verbatim to the
// snapshot so that it can be written in one, fast, memcpy during
// deserialization. The deserializer will overwrite some pointers, rather
@ -660,12 +630,8 @@ class InstructionStream : public HeapObject {
inline void initialize_flags(CodeKind kind, bool is_turbofanned,
int stack_slots);
// Convert a target address into a code object.
static inline InstructionStream GetCodeFromTargetAddress(Address address);
// Convert an entry address into an object.
static inline InstructionStream GetObjectFromEntryAddress(
Address location_of_address);
static inline InstructionStream FromTargetAddress(Address address);
static inline InstructionStream FromEntryAddress(Address location_of_address);
// Returns the size of code and its metadata. This includes the size of code
// relocation information, deoptimization data.
@ -755,7 +721,7 @@ class InstructionStream : public HeapObject {
class OptimizedCodeIterator;
// Layout description.
#define CODE_FIELDS(V) \
#define ISTREAM_FIELDS(V) \
V(kRelocationInfoOffset, kTaggedSize) \
V(kDeoptimizationDataOrInterpreterDataOffset, kTaggedSize) \
V(kPositionTableOffset, kTaggedSize) \
@ -783,8 +749,8 @@ class InstructionStream : public HeapObject {
V(kOptionalPaddingOffset, CODE_POINTER_PADDING(kOptionalPaddingOffset)) \
V(kHeaderSize, 0)
DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize, CODE_FIELDS)
#undef CODE_FIELDS
DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize, ISTREAM_FIELDS)
#undef ISTREAM_FIELDS
// This documents the amount of free space we have in each InstructionStream
// object header due to padding for code alignment.
@ -822,27 +788,27 @@ class InstructionStream : public HeapObject {
class BodyDescriptor;
// Flags layout. base::BitField<type, shift, size>.
#define CODE_FLAGS_BIT_FIELDS(V, _) \
V(KindField, CodeKind, 4, _) \
V(IsTurbofannedField, bool, 1, _) \
#define ISTREAM_FLAGS_BIT_FIELDS(V, _) \
V(KindField, CodeKind, 4, _) \
V(IsTurbofannedField, bool, 1, _) \
V(StackSlotsField, int, 24, _)
DEFINE_BIT_FIELDS(CODE_FLAGS_BIT_FIELDS)
#undef CODE_FLAGS_BIT_FIELDS
DEFINE_BIT_FIELDS(ISTREAM_FLAGS_BIT_FIELDS)
#undef ISTREAM_FLAGS_BIT_FIELDS
static_assert(kCodeKindCount <= KindField::kNumValues);
static_assert(CODE_FLAGS_BIT_FIELDS_Ranges::kBitsCount == 29);
static_assert(CODE_FLAGS_BIT_FIELDS_Ranges::kBitsCount <=
static_assert(ISTREAM_FLAGS_BIT_FIELDS_Ranges::kBitsCount == 29);
static_assert(ISTREAM_FLAGS_BIT_FIELDS_Ranges::kBitsCount <=
FIELD_SIZE(kFlagsOffset) * kBitsPerByte);
// KindSpecificFlags layout.
#define CODE_KIND_SPECIFIC_FLAGS_BIT_FIELDS(V, _) \
V(MarkedForDeoptimizationField, bool, 1, _) \
V(EmbeddedObjectsClearedField, bool, 1, _) \
V(CanHaveWeakObjectsField, bool, 1, _) \
#define ISTREAM_KIND_SPECIFIC_FLAGS_BIT_FIELDS(V, _) \
V(MarkedForDeoptimizationField, bool, 1, _) \
V(EmbeddedObjectsClearedField, bool, 1, _) \
V(CanHaveWeakObjectsField, bool, 1, _) \
V(IsPromiseRejectionField, bool, 1, _)
DEFINE_BIT_FIELDS(CODE_KIND_SPECIFIC_FLAGS_BIT_FIELDS)
#undef CODE_KIND_SPECIFIC_FLAGS_BIT_FIELDS
static_assert(CODE_KIND_SPECIFIC_FLAGS_BIT_FIELDS_Ranges::kBitsCount == 4);
static_assert(CODE_KIND_SPECIFIC_FLAGS_BIT_FIELDS_Ranges::kBitsCount <=
DEFINE_BIT_FIELDS(ISTREAM_KIND_SPECIFIC_FLAGS_BIT_FIELDS)
#undef ISTREAM_KIND_SPECIFIC_FLAGS_BIT_FIELDS
static_assert(ISTREAM_KIND_SPECIFIC_FLAGS_BIT_FIELDS_Ranges::kBitsCount == 4);
static_assert(ISTREAM_KIND_SPECIFIC_FLAGS_BIT_FIELDS_Ranges::kBitsCount <=
FIELD_SIZE(Code::kKindSpecificFlagsOffset) * kBitsPerByte);
// The {marked_for_deoptimization} field is accessed from generated code.
@ -875,38 +841,6 @@ class InstructionStream : public HeapObject {
OBJECT_CONSTRUCTORS(InstructionStream, HeapObject);
};
// TODO(v8:11880): move these functions to Code once they are no
// longer used from InstructionStream.
V8_EXPORT_PRIVATE Address OffHeapInstructionStart(HeapObject code,
Builtin builtin);
V8_EXPORT_PRIVATE Address OffHeapInstructionEnd(HeapObject code,
Builtin builtin);
V8_EXPORT_PRIVATE int OffHeapInstructionSize(HeapObject code, Builtin builtin);
V8_EXPORT_PRIVATE Address OffHeapMetadataStart(HeapObject code,
Builtin builtin);
V8_EXPORT_PRIVATE Address OffHeapMetadataEnd(HeapObject code, Builtin builtin);
V8_EXPORT_PRIVATE int OffHeapMetadataSize(HeapObject code, Builtin builtin);
V8_EXPORT_PRIVATE Address OffHeapSafepointTableAddress(HeapObject code,
Builtin builtin);
V8_EXPORT_PRIVATE int OffHeapSafepointTableSize(HeapObject code,
Builtin builtin);
V8_EXPORT_PRIVATE Address OffHeapHandlerTableAddress(HeapObject code,
Builtin builtin);
V8_EXPORT_PRIVATE int OffHeapHandlerTableSize(HeapObject code, Builtin builtin);
V8_EXPORT_PRIVATE Address OffHeapConstantPoolAddress(HeapObject code,
Builtin builtin);
V8_EXPORT_PRIVATE int OffHeapConstantPoolSize(HeapObject code, Builtin builtin);
V8_EXPORT_PRIVATE Address OffHeapCodeCommentsAddress(HeapObject code,
Builtin builtin);
V8_EXPORT_PRIVATE int OffHeapCodeCommentsSize(HeapObject code, Builtin builtin);
V8_EXPORT_PRIVATE Address OffHeapUnwindingInfoAddress(HeapObject code,
Builtin builtin);
V8_EXPORT_PRIVATE int OffHeapUnwindingInfoSize(HeapObject code,
Builtin builtin);
V8_EXPORT_PRIVATE int OffHeapStackSlots(HeapObject code, Builtin builtin);
class InstructionStream::OptimizedCodeIterator {
public:
explicit OptimizedCodeIterator(Isolate* isolate);

View File

@ -1081,7 +1081,7 @@ class IndexedReferencesExtractor : public ObjectVisitorWithCageBases {
void VisitCodeTarget(InstructionStream host, RelocInfo* rinfo) override {
InstructionStream target =
InstructionStream::GetCodeFromTargetAddress(rinfo->target_address());
InstructionStream::FromTargetAddress(rinfo->target_address());
VisitHeapObjectImpl(target, -1);
}

View File

@ -302,8 +302,8 @@ void ProfilerListener::CodeMoveEvent(InstructionStream from,
DisallowGarbageCollection no_gc;
CodeEventsContainer evt_rec(CodeEventRecord::Type::kCodeMove);
CodeMoveEventRecord* rec = &evt_rec.CodeMoveEventRecord_;
rec->from_instruction_start = from.InstructionStart();
rec->to_instruction_start = to.InstructionStart();
rec->from_instruction_start = from.instruction_start();
rec->to_instruction_start = to.instruction_start();
DispatchCodeEvent(evt_rec);
}
@ -340,7 +340,7 @@ void ProfilerListener::CodeDeoptEvent(Handle<InstructionStream> code,
CodeEventsContainer evt_rec(CodeEventRecord::Type::kCodeDeopt);
CodeDeoptEventRecord* rec = &evt_rec.CodeDeoptEventRecord_;
Deoptimizer::DeoptInfo info = Deoptimizer::GetDeoptInfo(*code, pc);
rec->instruction_start = code->InstructionStart();
rec->instruction_start = code->instruction_start();
rec->deopt_reason = DeoptimizeReasonToString(info.deopt_reason);
rec->deopt_id = info.deopt_id;
rec->pc = pc;

View File

@ -287,8 +287,8 @@ int NativeRegExpMacroAssembler::CheckStackGuardState(
const byte** input_start, const byte** input_end) {
DisallowGarbageCollection no_gc;
Address old_pc = PointerAuthentication::AuthenticatePC(return_address, 0);
DCHECK_LE(re_code.raw_instruction_start(), old_pc);
DCHECK_LE(old_pc, re_code.raw_instruction_end());
DCHECK_LE(re_code.instruction_start(), old_pc);
DCHECK_LE(old_pc, re_code.instruction_end());
StackLimitCheck check(isolate);
bool js_has_overflowed = check.JsHasOverflowed();

View File

@ -1019,16 +1019,16 @@ bool RegExpImpl::Compile(Isolate* isolate, Zone* zone, RegExpCompileData* data,
data->compilation_target == RegExpCompilationTarget::kNative) {
CodeTracer::Scope trace_scope(isolate->GetCodeTracer());
OFStream os(trace_scope.file());
Handle<InstructionStream> c =
Handle<InstructionStream>::cast(result.code);
auto pattern_cstring = pattern->ToCString();
c->Disassemble(pattern_cstring.get(), os, isolate);
Code code =
Handle<InstructionStream>::cast(result.code)->code(kAcquireLoad);
std::unique_ptr<char[]> pattern_cstring = pattern->ToCString();
code.Disassemble(pattern_cstring.get(), os, isolate);
}
#endif
if (v8_flags.print_regexp_bytecode &&
data->compilation_target == RegExpCompilationTarget::kBytecode) {
Handle<ByteArray> bytecode = Handle<ByteArray>::cast(result.code);
auto pattern_cstring = pattern->ToCString();
std::unique_ptr<char[]> pattern_cstring = pattern->ToCString();
RegExpBytecodeDisassemble(bytecode->GetDataStartAddress(),
bytecode->length(), pattern_cstring.get());
}

View File

@ -497,11 +497,11 @@ void Deserializer<IsolateT>::PostProcessNewObject(Handle<Map> map,
new_code_objects_.push_back(Handle<InstructionStream>::cast(obj));
}
} else if (InstanceTypeChecker::IsCode(instance_type)) {
auto code = Code::cast(raw_obj);
Code code = Code::cast(raw_obj);
code.init_code_entry_point(main_thread_isolate(), kNullAddress);
if (!code.has_instruction_stream()) {
Address entry = OffHeapInstructionStart(code, code.builtin_id());
code.SetEntryPointForOffHeapBuiltin(main_thread_isolate(), entry);
code.SetEntryPointForOffHeapBuiltin(main_thread_isolate(),
code.OffHeapInstructionStart());
} else {
code.UpdateCodeEntryPoint(main_thread_isolate(),
code.instruction_stream());
@ -753,7 +753,7 @@ void DeserializerRelocInfoVisitor::VisitCodeTarget(InstructionStream host,
RelocInfo* rinfo) {
HeapObject object = *objects_->at(current_object_++);
rinfo->set_target_address(
InstructionStream::cast(object).raw_instruction_start());
InstructionStream::cast(object).instruction_start());
}
void DeserializerRelocInfoVisitor::VisitEmbeddedPointer(InstructionStream host,
@ -784,14 +784,11 @@ void DeserializerRelocInfoVisitor::VisitInternalReference(
byte data = source().Get();
CHECK_EQ(data, Deserializer<Isolate>::kInternalReference);
// Internal reference target is encoded as an offset from code entry.
// An internal reference target is encoded as an offset from code entry.
int target_offset = source().GetInt();
// TODO(jgruber,v8:11036): We are being permissive for this DCHECK, but
// consider using raw_instruction_size() instead of raw_body_size() in the
// future.
static_assert(InstructionStream::kOnHeapBodyIsContiguous);
DCHECK_LT(static_cast<unsigned>(target_offset),
static_cast<unsigned>(host.raw_body_size()));
static_cast<unsigned>(host.instruction_size()));
Address target = host.entry() + target_offset;
Assembler::deserialization_set_target_internal_reference_at(
rinfo->pc(), target, rinfo->rmode());

View File

@ -238,7 +238,7 @@ void FinalizeEmbeddedCodeTargets(Isolate* isolate, EmbeddedData* blob) {
RelocInfo* rinfo = on_heap_it.rinfo();
DCHECK_EQ(rinfo->rmode(), off_heap_it.rinfo()->rmode());
InstructionStream target =
InstructionStream::GetCodeFromTargetAddress(rinfo->target_address());
InstructionStream::FromTargetAddress(rinfo->target_address());
CHECK(Builtins::IsIsolateIndependentBuiltin(target.code(kAcquireLoad)));
// Do not emit write-barrier for off-heap writes.
@ -303,9 +303,8 @@ EmbeddedData EmbeddedData::FromIsolate(Isolate* isolate) {
Builtins::name(builtin));
}
uint32_t instruction_size =
static_cast<uint32_t>(code.raw_instruction_size());
uint32_t metadata_size = static_cast<uint32_t>(code.raw_metadata_size());
uint32_t instruction_size = static_cast<uint32_t>(code.instruction_size());
uint32_t metadata_size = static_cast<uint32_t>(code.metadata_size());
DCHECK_EQ(0, raw_code_size % kCodeAlignment);
{
@ -378,10 +377,10 @@ EmbeddedData EmbeddedData::FromIsolate(Isolate* isolate) {
uint32_t offset =
layout_descriptions[static_cast<int>(builtin)].metadata_offset;
uint8_t* dst = raw_metadata_start + offset;
DCHECK_LE(RawMetadataOffset() + offset + code.raw_metadata_size(),
DCHECK_LE(RawMetadataOffset() + offset + code.metadata_size(),
blob_data_size);
std::memcpy(dst, reinterpret_cast<uint8_t*>(code.raw_metadata_start()),
code.raw_metadata_size());
std::memcpy(dst, reinterpret_cast<uint8_t*>(code.metadata_start()),
code.metadata_size());
}
CHECK_IMPLIES(
kMaxPCRelativeCodeRangeInMB,
@ -396,10 +395,10 @@ EmbeddedData EmbeddedData::FromIsolate(Isolate* isolate) {
uint32_t offset =
layout_descriptions[static_cast<int>(builtin)].instruction_offset;
uint8_t* dst = raw_code_start + offset;
DCHECK_LE(RawCodeOffset() + offset + code.raw_instruction_size(),
DCHECK_LE(RawCodeOffset() + offset + code.instruction_size(),
blob_code_size);
std::memcpy(dst, reinterpret_cast<uint8_t*>(code.raw_instruction_start()),
code.raw_instruction_size());
std::memcpy(dst, reinterpret_cast<uint8_t*>(code.instruction_start()),
code.instruction_size());
}
EmbeddedData d(blob_code, blob_code_size, blob_data, blob_data_size);
@ -430,8 +429,8 @@ EmbeddedData EmbeddedData::FromIsolate(Isolate* isolate) {
++builtin) {
InstructionStream code = FromCode(builtins->code(builtin));
CHECK_EQ(d.InstructionSizeOfBuiltin(builtin), code.InstructionSize());
CHECK_EQ(d.MetadataSizeOfBuiltin(builtin), code.MetadataSize());
CHECK_EQ(d.InstructionSizeOfBuiltin(builtin), code.instruction_size());
CHECK_EQ(d.MetadataSizeOfBuiltin(builtin), code.metadata_size());
CHECK_EQ(d.SafepointTableSizeOf(builtin), code.safepoint_table_size());
CHECK_EQ(d.HandlerTableSizeOf(builtin), code.handler_table_size());

View File

@ -1032,7 +1032,7 @@ class Serializer::ObjectSerializer::RelocInfoObjectPreSerializer {
DCHECK(!RelocInfo::IsRelativeCodeTarget(target->rmode()));
#endif
InstructionStream object =
InstructionStream::GetCodeFromTargetAddress(target->target_address());
InstructionStream::FromTargetAddress(target->target_address());
serializer_->SerializeObject(handle(object, isolate()));
num_serialized_objects_++;
}
@ -1074,15 +1074,12 @@ void Serializer::ObjectSerializer::VisitExternalReference(
void Serializer::ObjectSerializer::VisitInternalReference(
InstructionStream host, RelocInfo* rinfo) {
Address entry = Handle<InstructionStream>::cast(object_)->entry();
Handle<InstructionStream> istream = Handle<InstructionStream>::cast(object_);
Address entry = istream->entry();
DCHECK_GE(rinfo->target_internal_reference(), entry);
uintptr_t target_offset = rinfo->target_internal_reference() - entry;
// TODO(jgruber,v8:11036): We are being permissive for this DCHECK, but
// consider using raw_instruction_size() instead of raw_body_size() in the
// future.
static_assert(InstructionStream::kOnHeapBodyIsContiguous);
DCHECK_LE(target_offset,
Handle<InstructionStream>::cast(object_)->raw_body_size());
DCHECK_LT(target_offset, istream->instruction_size());
sink_->Put(kInternalReference, "InternalRef");
sink_->PutInt(target_offset, "internal ref value");
}

View File

@ -1428,7 +1428,7 @@ void RecordStats(Code code, Counters* counters) {
if (!code.has_instruction_stream()) return;
InstructionStream instruction_stream = FromCode(code);
counters->wasm_generated_code_size()->Increment(
instruction_stream.raw_body_size());
instruction_stream.body_size());
counters->wasm_reloc_size()->Increment(
instruction_stream.relocation_info().length());
}

View File

@ -901,14 +901,14 @@ WasmCode* NativeModule::AddCodeForTesting(Handle<InstructionStream> code) {
}
static_assert(InstructionStream::kOnHeapBodyIsContiguous);
base::Vector<const byte> instructions(
reinterpret_cast<byte*>(code->raw_body_start()),
static_cast<size_t>(code->raw_body_size()));
reinterpret_cast<byte*>(code->body_start()),
static_cast<size_t>(code->body_size()));
const int stack_slots = code->stack_slots();
// Metadata offsets in InstructionStream objects are relative to the start of
// the metadata section, whereas WasmCode expects offsets relative to
// InstructionStart.
const int base_offset = code->raw_instruction_size();
const int base_offset = code->instruction_size();
// TODO(jgruber,v8:8758): Remove this translation. It exists only because
// InstructionStream objects contains real offsets but WasmCode expects an
// offset of 0 to mean 'empty'.
@ -926,7 +926,7 @@ WasmCode* NativeModule::AddCodeForTesting(Handle<InstructionStream> code) {
// Apply the relocation delta by iterating over the RelocInfo.
intptr_t delta = reinterpret_cast<Address>(dst_code_bytes.begin()) -
code->raw_instruction_start();
code->instruction_start();
int mode_mask =
RelocInfo::kApplyMask | RelocInfo::ModeMask(RelocInfo::WASM_STUB_CALL);
auto jump_tables_ref =

View File

@ -187,7 +187,7 @@ void TestReturnMultipleValues(MachineType type, int min_count, int max_count) {
}
std::shared_ptr<wasm::NativeModule> module = AllocateNativeModule(
handles.main_isolate(), istream->raw_instruction_size());
handles.main_isolate(), istream->instruction_size());
wasm::WasmCodeRefScope wasm_code_ref_scope;
byte* code_start =
module->AddCodeForTesting(istream)->instructions().begin();
@ -218,9 +218,9 @@ void TestReturnMultipleValues(MachineType type, int min_count, int max_count) {
}
mt.Return(ToInt32(&mt, type, ret));
#ifdef ENABLE_DISASSEMBLER
Handle<InstructionStream> code2 = mt.GetInstructionStream();
if (v8_flags.print_code) {
StdoutStream os;
Handle<Code> code2 = mt.GetCode();
code2->Disassemble("multi_value_call", os, handles.main_isolate());
}
#endif
@ -286,7 +286,7 @@ void ReturnLastValue(MachineType type) {
handles.main_isolate());
std::shared_ptr<wasm::NativeModule> module = AllocateNativeModule(
handles.main_isolate(), istream->raw_instruction_size());
handles.main_isolate(), istream->instruction_size());
wasm::WasmCodeRefScope wasm_code_ref_scope;
byte* code_start =
module->AddCodeForTesting(istream)->instructions().begin();
@ -352,7 +352,7 @@ void ReturnSumOfReturns(MachineType type) {
handles.main_isolate());
std::shared_ptr<wasm::NativeModule> module = AllocateNativeModule(
handles.main_isolate(), istream->raw_instruction_size());
handles.main_isolate(), istream->instruction_size());
wasm::WasmCodeRefScope wasm_code_ref_scope;
byte* code_start =
module->AddCodeForTesting(istream)->instructions().begin();

View File

@ -21,9 +21,9 @@ std::string DisassembleFunction(const char* function) {
CcTest::global()->Get(context, v8_str(function)).ToLocalChecked())));
Isolate* isolate = CcTest::i_isolate();
Handle<InstructionStream> code(FromCode(f->code()), isolate);
Address begin = code->raw_instruction_start();
Address end = code->raw_instruction_end();
Handle<Code> code(f->code(), isolate);
Address begin = code->InstructionStart();
Address end = code->InstructionEnd();
std::ostringstream os;
Disassembler::Decode(isolate, os, reinterpret_cast<byte*>(begin),
reinterpret_cast<byte*>(end), CodeReference(code));

View File

@ -305,9 +305,9 @@ TEST(Unwind_CodeObjectPCInMiddle_Success_CodePagesAPI) {
// We don't want the offset too early or it could be the `push rbp`
// instruction (which is not at the start of generated code, because the lazy
// deopt check happens before frame setup).
const uintptr_t offset = instruction_stream.InstructionSize() - 20;
CHECK_LT(offset, instruction_stream.InstructionSize());
Address pc = instruction_stream.InstructionStart() + offset;
const uintptr_t offset = instruction_stream.instruction_size() - 20;
CHECK_LT(offset, instruction_stream.instruction_size());
Address pc = instruction_stream.instruction_start() + offset;
register_state.pc = reinterpret_cast<void*>(pc);
// Get code pages from the API now that the code obejct exists and check that
@ -680,7 +680,7 @@ TEST(PCIsInV8_LargeCodeObject_CodePagesAPI) {
i_isolate);
CHECK(i_isolate->heap()->InSpace(*foo_code, CODE_LO_SPACE));
byte* start = reinterpret_cast<byte*>(foo_code->InstructionStart());
byte* start = reinterpret_cast<byte*>(foo_code->instruction_start());
MemoryRange code_pages[v8::Isolate::kMinCodePagesBufferSize];
size_t pages_length =