[offthread] Add OffThreadIsolate support to bytecode generator
Bug: chromium:1011762 Change-Id: I58284d50acaf349ed5c56654972e2c2bcece1ec3 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2061550 Commit-Queue: Leszek Swirski <leszeks@chromium.org> Reviewed-by: Ross McIlroy <rmcilroy@chromium.org> Cr-Commit-Position: refs/heads/master@{#66378}
This commit is contained in:
parent
edad3a0f0f
commit
9bb73365eb
@ -164,7 +164,8 @@ CompilationJob::Status UnoptimizedCompilationJob::FinalizeJob(
|
||||
void UnoptimizedCompilationJob::RecordCompilationStats(Isolate* isolate) const {
|
||||
int code_size;
|
||||
if (compilation_info()->has_bytecode_array()) {
|
||||
code_size = compilation_info()->bytecode_array()->SizeIncludingMetadata();
|
||||
code_size =
|
||||
compilation_info()->bytecode_array<Isolate>()->SizeIncludingMetadata();
|
||||
} else {
|
||||
DCHECK(compilation_info()->has_asm_wasm_data());
|
||||
code_size = compilation_info()->asm_wasm_data()->Size();
|
||||
@ -184,8 +185,8 @@ void UnoptimizedCompilationJob::RecordFunctionCompilation(
|
||||
Isolate* isolate) const {
|
||||
Handle<AbstractCode> abstract_code;
|
||||
if (compilation_info()->has_bytecode_array()) {
|
||||
abstract_code =
|
||||
Handle<AbstractCode>::cast(compilation_info()->bytecode_array());
|
||||
abstract_code = Handle<AbstractCode>::cast(
|
||||
compilation_info()->bytecode_array<Isolate>());
|
||||
} else {
|
||||
DCHECK(compilation_info()->has_asm_wasm_data());
|
||||
abstract_code =
|
||||
@ -420,8 +421,8 @@ void InstallUnoptimizedCode(UnoptimizedCompilationInfo* compilation_info,
|
||||
shared_info->set_is_asm_wasm_broken(true);
|
||||
}
|
||||
|
||||
InstallBytecodeArray(compilation_info->bytecode_array(), shared_info,
|
||||
parse_info, isolate);
|
||||
InstallBytecodeArray(compilation_info->bytecode_array<Isolate>(),
|
||||
shared_info, parse_info, isolate);
|
||||
|
||||
Handle<FeedbackMetadata> feedback_metadata = FeedbackMetadata::New(
|
||||
isolate, compilation_info->feedback_vector_spec());
|
||||
@ -437,8 +438,8 @@ void InstallUnoptimizedCode(UnoptimizedCompilationInfo* compilation_info,
|
||||
if (compilation_info->has_coverage_info() &&
|
||||
!shared_info->HasCoverageInfo()) {
|
||||
DCHECK(isolate->is_block_code_coverage());
|
||||
isolate->debug()->InstallCoverageInfo(shared_info,
|
||||
compilation_info->coverage_info());
|
||||
isolate->debug()->InstallCoverageInfo(
|
||||
shared_info, compilation_info->coverage_info<Isolate>());
|
||||
}
|
||||
}
|
||||
|
||||
@ -1282,8 +1283,9 @@ bool Compiler::CollectSourcePositions(Isolate* isolate,
|
||||
// table set on it as well.
|
||||
if (shared_info->HasDebugInfo() &&
|
||||
shared_info->GetDebugInfo().HasInstrumentedBytecodeArray()) {
|
||||
ByteArray source_position_table =
|
||||
job->compilation_info()->bytecode_array()->SourcePositionTable();
|
||||
ByteArray source_position_table = job->compilation_info()
|
||||
->bytecode_array<Isolate>()
|
||||
->SourcePositionTable();
|
||||
shared_info->GetDebugBytecodeArray().set_source_position_table(
|
||||
source_position_table);
|
||||
}
|
||||
@ -2259,23 +2261,25 @@ Compiler::GetSharedFunctionInfoForStreamedScript(
|
||||
return maybe_result;
|
||||
}
|
||||
|
||||
Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfo(
|
||||
FunctionLiteral* literal, Handle<Script> script, Isolate* isolate) {
|
||||
template <typename Isolate>
|
||||
HandleFor<Isolate, SharedFunctionInfo> Compiler::GetSharedFunctionInfo(
|
||||
FunctionLiteral* literal, HandleFor<Isolate, Script> script,
|
||||
Isolate* isolate) {
|
||||
// Precondition: code has been parsed and scopes have been analyzed.
|
||||
MaybeHandle<SharedFunctionInfo> maybe_existing;
|
||||
MaybeHandleFor<Isolate, SharedFunctionInfo> maybe_existing;
|
||||
|
||||
// Find any previously allocated shared function info for the given literal.
|
||||
maybe_existing = script->FindSharedFunctionInfo(isolate, literal);
|
||||
|
||||
// If we found an existing shared function info, return it.
|
||||
Handle<SharedFunctionInfo> existing;
|
||||
HandleFor<Isolate, SharedFunctionInfo> existing;
|
||||
if (maybe_existing.ToHandle(&existing)) {
|
||||
// If the function has been uncompiled (bytecode flushed) it will have lost
|
||||
// any preparsed data. If we produced preparsed data during this compile for
|
||||
// this function, replace the uncompiled data with one that includes it.
|
||||
if (literal->produced_preparse_data() != nullptr &&
|
||||
existing->HasUncompiledDataWithoutPreparseData()) {
|
||||
Handle<UncompiledData> existing_uncompiled_data =
|
||||
HandleFor<Isolate, UncompiledData> existing_uncompiled_data =
|
||||
handle(existing->uncompiled_data(), isolate);
|
||||
DCHECK_EQ(literal->start_position(),
|
||||
existing_uncompiled_data->start_position());
|
||||
@ -2283,11 +2287,11 @@ Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfo(
|
||||
existing_uncompiled_data->end_position());
|
||||
// Use existing uncompiled data's inferred name as it may be more
|
||||
// accurate than the literal we preparsed.
|
||||
Handle<String> inferred_name =
|
||||
HandleFor<Isolate, String> inferred_name =
|
||||
handle(existing_uncompiled_data->inferred_name(), isolate);
|
||||
Handle<PreparseData> preparse_data =
|
||||
HandleFor<Isolate, PreparseData> preparse_data =
|
||||
literal->produced_preparse_data()->Serialize(isolate);
|
||||
Handle<UncompiledData> new_uncompiled_data =
|
||||
HandleFor<Isolate, UncompiledData> new_uncompiled_data =
|
||||
isolate->factory()->NewUncompiledDataWithPreparseData(
|
||||
inferred_name, existing_uncompiled_data->start_position(),
|
||||
existing_uncompiled_data->end_position(), preparse_data);
|
||||
@ -2297,12 +2301,18 @@ Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfo(
|
||||
}
|
||||
|
||||
// Allocate a shared function info object which will be compiled lazily.
|
||||
Handle<SharedFunctionInfo> result =
|
||||
HandleFor<Isolate, SharedFunctionInfo> result =
|
||||
isolate->factory()->NewSharedFunctionInfoForLiteral(literal, script,
|
||||
false);
|
||||
return result;
|
||||
}
|
||||
|
||||
template Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfo(
|
||||
FunctionLiteral* literal, Handle<Script> script, Isolate* isolate);
|
||||
template OffThreadHandle<SharedFunctionInfo> Compiler::GetSharedFunctionInfo(
|
||||
FunctionLiteral* literal, OffThreadHandle<Script> script,
|
||||
OffThreadIsolate* isolate);
|
||||
|
||||
MaybeHandle<Code> Compiler::GetOptimizedCodeForOSR(Handle<JSFunction> function,
|
||||
BailoutId osr_offset,
|
||||
JavaScriptFrame* osr_frame) {
|
||||
|
@ -176,9 +176,10 @@ class V8_EXPORT_PRIVATE Compiler : public AllStatic {
|
||||
|
||||
// Create a shared function info object for the given function literal
|
||||
// node (the code may be lazily compiled).
|
||||
static Handle<SharedFunctionInfo> GetSharedFunctionInfo(FunctionLiteral* node,
|
||||
Handle<Script> script,
|
||||
Isolate* isolate);
|
||||
template <typename Isolate>
|
||||
static HandleFor<Isolate, SharedFunctionInfo> GetSharedFunctionInfo(
|
||||
FunctionLiteral* node, HandleFor<Isolate, Script> script,
|
||||
Isolate* isolate);
|
||||
|
||||
// ===========================================================================
|
||||
// The following family of methods provides support for OSR. Code generated
|
||||
|
@ -4,6 +4,8 @@
|
||||
|
||||
#include "src/codegen/source-position-table.h"
|
||||
|
||||
#include "src/base/export-template.h"
|
||||
#include "src/heap/off-thread-factory-inl.h"
|
||||
#include "src/objects/objects-inl.h"
|
||||
#include "src/objects/objects.h"
|
||||
|
||||
@ -153,12 +155,13 @@ void SourcePositionTableBuilder::AddEntry(const PositionTableEntry& entry) {
|
||||
#endif
|
||||
}
|
||||
|
||||
Handle<ByteArray> SourcePositionTableBuilder::ToSourcePositionTable(
|
||||
template <typename Isolate>
|
||||
HandleFor<Isolate, ByteArray> SourcePositionTableBuilder::ToSourcePositionTable(
|
||||
Isolate* isolate) {
|
||||
if (bytes_.empty()) return isolate->factory()->empty_byte_array();
|
||||
DCHECK(!Omit());
|
||||
|
||||
Handle<ByteArray> table = isolate->factory()->NewByteArray(
|
||||
HandleFor<Isolate, ByteArray> table = isolate->factory()->NewByteArray(
|
||||
static_cast<int>(bytes_.size()), AllocationType::kOld);
|
||||
MemCopy(table->GetDataStartAddress(), bytes_.data(), bytes_.size());
|
||||
|
||||
@ -175,6 +178,13 @@ Handle<ByteArray> SourcePositionTableBuilder::ToSourcePositionTable(
|
||||
return table;
|
||||
}
|
||||
|
||||
template EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
|
||||
Handle<ByteArray> SourcePositionTableBuilder::ToSourcePositionTable(
|
||||
Isolate* isolate);
|
||||
template EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
|
||||
OffThreadHandle<ByteArray> SourcePositionTableBuilder::
|
||||
ToSourcePositionTable(OffThreadIsolate* isolate);
|
||||
|
||||
OwnedVector<byte> SourcePositionTableBuilder::ToSourcePositionTableVector() {
|
||||
if (bytes_.empty()) return OwnedVector<byte>();
|
||||
DCHECK(!Omit());
|
||||
|
@ -5,6 +5,7 @@
|
||||
#ifndef V8_CODEGEN_SOURCE_POSITION_TABLE_H_
|
||||
#define V8_CODEGEN_SOURCE_POSITION_TABLE_H_
|
||||
|
||||
#include "src/base/export-template.h"
|
||||
#include "src/codegen/source-position.h"
|
||||
#include "src/common/assert-scope.h"
|
||||
#include "src/common/checks.h"
|
||||
@ -53,7 +54,9 @@ class V8_EXPORT_PRIVATE SourcePositionTableBuilder {
|
||||
void AddPosition(size_t code_offset, SourcePosition source_position,
|
||||
bool is_statement);
|
||||
|
||||
Handle<ByteArray> ToSourcePositionTable(Isolate* isolate);
|
||||
template <typename Isolate>
|
||||
EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE)
|
||||
HandleFor<Isolate, ByteArray> ToSourcePositionTable(Isolate* isolate);
|
||||
OwnedVector<byte> ToSourcePositionTableVector();
|
||||
|
||||
inline bool Omit() const { return mode_ != RECORD_SOURCE_POSITIONS; }
|
||||
|
@ -75,16 +75,22 @@ class V8_EXPORT_PRIVATE UnoptimizedCompilationInfo final {
|
||||
}
|
||||
|
||||
bool has_coverage_info() const { return !coverage_info_.is_null(); }
|
||||
Handle<CoverageInfo> coverage_info() const { return coverage_info_; }
|
||||
void set_coverage_info(Handle<CoverageInfo> coverage_info) {
|
||||
template <typename Isolate>
|
||||
HandleFor<Isolate, CoverageInfo> coverage_info() const {
|
||||
return coverage_info_.get<Isolate>();
|
||||
}
|
||||
void set_coverage_info(HandleOrOffThreadHandle<CoverageInfo> coverage_info) {
|
||||
coverage_info_ = coverage_info;
|
||||
}
|
||||
|
||||
// Accessors for the output of compilation.
|
||||
|
||||
bool has_bytecode_array() const { return !bytecode_array_.is_null(); }
|
||||
Handle<BytecodeArray> bytecode_array() const { return bytecode_array_; }
|
||||
void SetBytecodeArray(Handle<BytecodeArray> bytecode_array) {
|
||||
template <typename Isolate>
|
||||
HandleFor<Isolate, BytecodeArray> bytecode_array() const {
|
||||
return bytecode_array_.get<Isolate>();
|
||||
}
|
||||
void SetBytecodeArray(HandleOrOffThreadHandle<BytecodeArray> bytecode_array) {
|
||||
bytecode_array_ = bytecode_array;
|
||||
}
|
||||
|
||||
@ -124,10 +130,10 @@ class V8_EXPORT_PRIVATE UnoptimizedCompilationInfo final {
|
||||
|
||||
// Encapsulates coverage information gathered by the bytecode generator.
|
||||
// Needs to be stored on the shared function info once compilation completes.
|
||||
Handle<CoverageInfo> coverage_info_;
|
||||
HandleOrOffThreadHandle<CoverageInfo> coverage_info_;
|
||||
|
||||
// Holds the bytecode array generated by the interpreter.
|
||||
Handle<BytecodeArray> bytecode_array_;
|
||||
HandleOrOffThreadHandle<BytecodeArray> bytecode_array_;
|
||||
|
||||
// Holds the asm_wasm data struct generated by the asmjs compiler.
|
||||
Handle<AsmWasmData> asm_wasm_data_;
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "src/execution/off-thread-isolate.h"
|
||||
|
||||
#include "src/execution/isolate.h"
|
||||
#include "src/execution/thread-id.h"
|
||||
#include "src/logging/off-thread-logger.h"
|
||||
|
||||
namespace v8 {
|
||||
@ -13,7 +14,8 @@ namespace internal {
|
||||
OffThreadIsolate::OffThreadIsolate(Isolate* isolate)
|
||||
: HiddenOffThreadFactory(isolate),
|
||||
isolate_(isolate),
|
||||
logger_(new OffThreadLogger()) {}
|
||||
logger_(new OffThreadLogger()),
|
||||
thread_id_(ThreadId::Current()) {}
|
||||
OffThreadIsolate::~OffThreadIsolate() { delete logger_; }
|
||||
|
||||
int OffThreadIsolate::GetNextScriptId() { return isolate_->GetNextScriptId(); }
|
||||
|
@ -6,6 +6,7 @@
|
||||
#define V8_EXECUTION_OFF_THREAD_ISOLATE_H_
|
||||
|
||||
#include "src/base/logging.h"
|
||||
#include "src/execution/thread-id.h"
|
||||
#include "src/handles/handle-for.h"
|
||||
#include "src/heap/off-thread-factory.h"
|
||||
|
||||
@ -70,12 +71,15 @@ class V8_EXPORT_PRIVATE OffThreadIsolate final
|
||||
|
||||
OffThreadLogger* logger() { return logger_; }
|
||||
|
||||
ThreadId thread_id() { return thread_id_; }
|
||||
|
||||
private:
|
||||
// TODO(leszeks): Extract out the fields of the Isolate we want and store
|
||||
// those instead of the whole thing.
|
||||
Isolate* isolate_;
|
||||
|
||||
OffThreadLogger* logger_;
|
||||
ThreadId thread_id_;
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
@ -260,11 +260,11 @@ class HandleOrOffThreadHandle {
|
||||
}
|
||||
|
||||
// Explicit getters for the Handle and OffThreadHandle.
|
||||
inline Handle<T> get_handle() {
|
||||
inline Handle<T> get_handle() const {
|
||||
DCHECK_NE(which_, kOffThreadHandle);
|
||||
return Handle<T>(reinterpret_cast<Address*>(value_));
|
||||
}
|
||||
inline OffThreadHandle<T> get_off_thread_handle() {
|
||||
inline OffThreadHandle<T> get_off_thread_handle() const {
|
||||
DCHECK_NE(which_, kHandle);
|
||||
return OffThreadHandle<T>(T::unchecked_cast(Object(value_)));
|
||||
}
|
||||
@ -272,21 +272,21 @@ class HandleOrOffThreadHandle {
|
||||
// Implicitly convert to Handle, MaybeHandle and OffThreadHandle, whenever
|
||||
// the conversion can be implicit.
|
||||
template <typename U>
|
||||
operator Handle<U>() { // NOLINT
|
||||
operator Handle<U>() const { // NOLINT
|
||||
return get_handle();
|
||||
}
|
||||
template <typename U>
|
||||
operator MaybeHandle<U>() { // NOLINT
|
||||
operator MaybeHandle<U>() const { // NOLINT
|
||||
return get_handle();
|
||||
}
|
||||
template <typename U>
|
||||
operator OffThreadHandle<U>() { // NOLINT
|
||||
operator OffThreadHandle<U>() const { // NOLINT
|
||||
return get_off_thread_handle();
|
||||
}
|
||||
|
||||
// Allow templated dispatch on which type of handle to get.
|
||||
template <typename IsolateType>
|
||||
inline HandleFor<IsolateType, T> get() {
|
||||
inline HandleFor<IsolateType, T> get() const {
|
||||
return get_for(Tag<IsolateType>());
|
||||
}
|
||||
|
||||
@ -302,8 +302,8 @@ class HandleOrOffThreadHandle {
|
||||
template <typename IsolateType>
|
||||
struct Tag {};
|
||||
|
||||
V8_INLINE Handle<T> get_for(Tag<class Isolate>) { return get_handle(); }
|
||||
V8_INLINE OffThreadHandle<T> get_for(Tag<class OffThreadIsolate>) {
|
||||
V8_INLINE Handle<T> get_for(Tag<class Isolate>) const { return get_handle(); }
|
||||
V8_INLINE OffThreadHandle<T> get_for(Tag<class OffThreadIsolate>) const {
|
||||
return get_off_thread_handle();
|
||||
}
|
||||
|
||||
|
@ -4,10 +4,12 @@
|
||||
|
||||
#include "src/heap/factory-base.h"
|
||||
|
||||
#include "src/ast/ast-source-ranges.h"
|
||||
#include "src/ast/ast.h"
|
||||
#include "src/execution/off-thread-isolate.h"
|
||||
#include "src/handles/handles-inl.h"
|
||||
#include "src/heap/factory.h"
|
||||
#include "src/heap/heap-inl.h"
|
||||
#include "src/heap/off-thread-factory-inl.h"
|
||||
#include "src/heap/read-only-heap.h"
|
||||
#include "src/logging/log.h"
|
||||
@ -143,6 +145,54 @@ HandleFor<Impl, WeakFixedArray> FactoryBase<Impl>::NewWeakFixedArray(
|
||||
length, allocation);
|
||||
}
|
||||
|
||||
template <typename Impl>
|
||||
HandleFor<Impl, ByteArray> FactoryBase<Impl>::NewByteArray(
|
||||
int length, AllocationType allocation) {
|
||||
if (length < 0 || length > ByteArray::kMaxLength) {
|
||||
isolate()->FatalProcessOutOfHeapMemory("invalid array length");
|
||||
}
|
||||
int size = ByteArray::SizeFor(length);
|
||||
HeapObject result = AllocateRawWithImmortalMap(
|
||||
size, allocation, read_only_roots().byte_array_map());
|
||||
HandleFor<Impl, ByteArray> array(ByteArray::cast(result), isolate());
|
||||
array->set_length(length);
|
||||
array->clear_padding();
|
||||
return array;
|
||||
}
|
||||
|
||||
template <typename Impl>
|
||||
HandleFor<Impl, BytecodeArray> FactoryBase<Impl>::NewBytecodeArray(
|
||||
int length, const byte* raw_bytecodes, int frame_size, int parameter_count,
|
||||
HandleFor<Impl, FixedArray> constant_pool) {
|
||||
if (length < 0 || length > BytecodeArray::kMaxLength) {
|
||||
isolate()->FatalProcessOutOfHeapMemory("invalid array length");
|
||||
}
|
||||
// Bytecode array is AllocationType::kOld, so constant pool array should be
|
||||
// too.
|
||||
DCHECK(!Heap::InYoungGeneration(*constant_pool));
|
||||
|
||||
int size = BytecodeArray::SizeFor(length);
|
||||
HeapObject result = AllocateRawWithImmortalMap(
|
||||
size, AllocationType::kOld, read_only_roots().bytecode_array_map());
|
||||
HandleFor<Impl, BytecodeArray> instance(BytecodeArray::cast(result),
|
||||
isolate());
|
||||
instance->set_length(length);
|
||||
instance->set_frame_size(frame_size);
|
||||
instance->set_parameter_count(parameter_count);
|
||||
instance->set_incoming_new_target_or_generator_register(
|
||||
interpreter::Register::invalid_value());
|
||||
instance->set_osr_loop_nesting_level(0);
|
||||
instance->set_bytecode_age(BytecodeArray::kNoAgeBytecodeAge);
|
||||
instance->set_constant_pool(*constant_pool);
|
||||
instance->set_handler_table(read_only_roots().empty_byte_array());
|
||||
instance->set_source_position_table(read_only_roots().undefined_value());
|
||||
CopyBytes(reinterpret_cast<byte*>(instance->GetFirstBytecodeAddress()),
|
||||
raw_bytecodes, length);
|
||||
instance->clear_padding();
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
template <typename Impl>
|
||||
HandleFor<Impl, Script> FactoryBase<Impl>::NewScript(
|
||||
HandleFor<Impl, String> source) {
|
||||
@ -350,6 +400,26 @@ FactoryBase<Impl>::NewTemplateObjectDescription(
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename Impl>
|
||||
HandleFor<Impl, CoverageInfo> FactoryBase<Impl>::NewCoverageInfo(
|
||||
const ZoneVector<SourceRange>& slots) {
|
||||
const int slot_count = static_cast<int>(slots.size());
|
||||
|
||||
int size = CoverageInfo::SizeFor(slot_count);
|
||||
Map map = read_only_roots().coverage_info_map();
|
||||
HeapObject result =
|
||||
AllocateRawWithImmortalMap(size, AllocationType::kYoung, map);
|
||||
HandleFor<Impl, CoverageInfo> info(CoverageInfo::cast(result), isolate());
|
||||
|
||||
info->set_slot_count(slot_count);
|
||||
for (int i = 0; i < slot_count; i++) {
|
||||
SourceRange range = slots[i];
|
||||
info->InitializeSlot(i, range.start, range.end);
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
template <typename Impl>
|
||||
HandleFor<Impl, SeqOneByteString>
|
||||
FactoryBase<Impl>::NewOneByteInternalizedString(
|
||||
|
@ -28,6 +28,11 @@ class SourceTextModuleInfo;
|
||||
class PreparseData;
|
||||
class UncompiledDataWithoutPreparseData;
|
||||
class UncompiledDataWithPreparseData;
|
||||
class BytecodeArray;
|
||||
class CoverageInfo;
|
||||
struct SourceRange;
|
||||
template <typename T>
|
||||
class ZoneVector;
|
||||
|
||||
template <typename Impl>
|
||||
class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) FactoryBase {
|
||||
@ -89,6 +94,13 @@ class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) FactoryBase {
|
||||
HandleFor<Impl, WeakFixedArray> NewWeakFixedArray(
|
||||
int length, AllocationType allocation = AllocationType::kYoung);
|
||||
|
||||
HandleFor<Impl, ByteArray> NewByteArray(
|
||||
int length, AllocationType allocation = AllocationType::kYoung);
|
||||
|
||||
HandleFor<Impl, BytecodeArray> NewBytecodeArray(
|
||||
int length, const byte* raw_bytecodes, int frame_size,
|
||||
int parameter_count, HandleFor<Impl, FixedArray> constant_pool);
|
||||
|
||||
// Allocates a fixed array for name-value pairs of boilerplate properties and
|
||||
// calculates the number of properties we need to store in the backing store.
|
||||
HandleFor<Impl, ObjectBoilerplateDescription> NewObjectBoilerplateDescription(
|
||||
@ -126,6 +138,9 @@ class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) FactoryBase {
|
||||
int32_t end_position,
|
||||
HandleFor<Impl, PreparseData>);
|
||||
|
||||
HandleFor<Impl, CoverageInfo> NewCoverageInfo(
|
||||
const ZoneVector<SourceRange>& slots);
|
||||
|
||||
HandleFor<Impl, SeqOneByteString> NewOneByteInternalizedString(
|
||||
const Vector<const uint8_t>& str, uint32_t hash_field);
|
||||
HandleFor<Impl, SeqTwoByteString> NewTwoByteInternalizedString(
|
||||
|
@ -1328,50 +1328,6 @@ Handle<Foreign> Factory::NewForeign(Address addr) {
|
||||
return foreign;
|
||||
}
|
||||
|
||||
Handle<ByteArray> Factory::NewByteArray(int length, AllocationType allocation) {
|
||||
if (length < 0 || length > ByteArray::kMaxLength) {
|
||||
isolate()->heap()->FatalProcessOutOfMemory("invalid array length");
|
||||
}
|
||||
int size = ByteArray::SizeFor(length);
|
||||
HeapObject result =
|
||||
AllocateRawWithImmortalMap(size, allocation, *byte_array_map());
|
||||
Handle<ByteArray> array(ByteArray::cast(result), isolate());
|
||||
array->set_length(length);
|
||||
array->clear_padding();
|
||||
return array;
|
||||
}
|
||||
|
||||
Handle<BytecodeArray> Factory::NewBytecodeArray(
|
||||
int length, const byte* raw_bytecodes, int frame_size, int parameter_count,
|
||||
Handle<FixedArray> constant_pool) {
|
||||
if (length < 0 || length > BytecodeArray::kMaxLength) {
|
||||
isolate()->heap()->FatalProcessOutOfMemory("invalid array length");
|
||||
}
|
||||
// Bytecode array is AllocationType::kOld, so constant pool array should be
|
||||
// too.
|
||||
DCHECK(!Heap::InYoungGeneration(*constant_pool));
|
||||
|
||||
int size = BytecodeArray::SizeFor(length);
|
||||
HeapObject result = AllocateRawWithImmortalMap(size, AllocationType::kOld,
|
||||
*bytecode_array_map());
|
||||
Handle<BytecodeArray> instance(BytecodeArray::cast(result), isolate());
|
||||
instance->set_length(length);
|
||||
instance->set_frame_size(frame_size);
|
||||
instance->set_parameter_count(parameter_count);
|
||||
instance->set_incoming_new_target_or_generator_register(
|
||||
interpreter::Register::invalid_value());
|
||||
instance->set_osr_loop_nesting_level(0);
|
||||
instance->set_bytecode_age(BytecodeArray::kNoAgeBytecodeAge);
|
||||
instance->set_constant_pool(*constant_pool);
|
||||
instance->set_handler_table(*empty_byte_array());
|
||||
instance->set_source_position_table(*undefined_value());
|
||||
CopyBytes(reinterpret_cast<byte*>(instance->GetFirstBytecodeAddress()),
|
||||
raw_bytecodes, length);
|
||||
instance->clear_padding();
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
Handle<Cell> Factory::NewCell(Handle<Object> value) {
|
||||
STATIC_ASSERT(Cell::kSize <= kMaxRegularHeapObjectSize);
|
||||
HeapObject result = AllocateRawWithImmortalMap(
|
||||
@ -3118,25 +3074,6 @@ Handle<DebugInfo> Factory::NewDebugInfo(Handle<SharedFunctionInfo> shared) {
|
||||
return debug_info;
|
||||
}
|
||||
|
||||
Handle<CoverageInfo> Factory::NewCoverageInfo(
|
||||
const ZoneVector<SourceRange>& slots) {
|
||||
const int slot_count = static_cast<int>(slots.size());
|
||||
|
||||
int size = CoverageInfo::SizeFor(slot_count);
|
||||
Map map = read_only_roots().coverage_info_map();
|
||||
HeapObject result =
|
||||
AllocateRawWithImmortalMap(size, AllocationType::kYoung, map);
|
||||
Handle<CoverageInfo> info(CoverageInfo::cast(result), isolate());
|
||||
|
||||
info->set_slot_count(slot_count);
|
||||
for (int i = 0; i < slot_count; i++) {
|
||||
SourceRange range = slots[i];
|
||||
info->InitializeSlot(i, range.start, range.end);
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
Handle<BreakPointInfo> Factory::NewBreakPointInfo(int source_position) {
|
||||
Handle<BreakPointInfo> new_break_point_info = Handle<BreakPointInfo>::cast(
|
||||
NewStruct(BREAK_POINT_INFO_TYPE, AllocationType::kOld));
|
||||
|
@ -67,9 +67,6 @@ class WasmCapiFunctionData;
|
||||
class WasmExportedFunctionData;
|
||||
class WasmJSFunctionData;
|
||||
class WeakCell;
|
||||
struct SourceRange;
|
||||
template <typename T>
|
||||
class ZoneVector;
|
||||
enum class SharedFlag : uint8_t;
|
||||
enum class InitializedFlag : uint8_t;
|
||||
|
||||
@ -397,13 +394,6 @@ class V8_EXPORT_PRIVATE Factory : public FactoryBase<Factory> {
|
||||
// Foreign objects are pretenured when allocated by the bootstrapper.
|
||||
Handle<Foreign> NewForeign(Address addr);
|
||||
|
||||
Handle<ByteArray> NewByteArray(
|
||||
int length, AllocationType allocation = AllocationType::kYoung);
|
||||
|
||||
Handle<BytecodeArray> NewBytecodeArray(int length, const byte* raw_bytecodes,
|
||||
int frame_size, int parameter_count,
|
||||
Handle<FixedArray> constant_pool);
|
||||
|
||||
Handle<Cell> NewCell(Handle<Object> value);
|
||||
|
||||
Handle<PropertyCell> NewPropertyCell(
|
||||
@ -765,8 +755,6 @@ class V8_EXPORT_PRIVATE Factory : public FactoryBase<Factory> {
|
||||
Handle<ClassPositions> NewClassPositions(int start, int end);
|
||||
Handle<DebugInfo> NewDebugInfo(Handle<SharedFunctionInfo> shared);
|
||||
|
||||
Handle<CoverageInfo> NewCoverageInfo(const ZoneVector<SourceRange>& slots);
|
||||
|
||||
// Return a map for given number of properties using the map cache in the
|
||||
// native context.
|
||||
Handle<Map> ObjectLiteralMapFromCache(Handle<NativeContext> native_context,
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include "src/interpreter/bytecode-array-builder.h"
|
||||
|
||||
#include "src/common/assert-scope.h"
|
||||
#include "src/common/globals.h"
|
||||
#include "src/interpreter/bytecode-array-writer.h"
|
||||
#include "src/interpreter/bytecode-jump-table.h"
|
||||
@ -81,7 +82,9 @@ Register BytecodeArrayBuilder::Local(int index) const {
|
||||
return Register(index);
|
||||
}
|
||||
|
||||
Handle<BytecodeArray> BytecodeArrayBuilder::ToBytecodeArray(Isolate* isolate) {
|
||||
template <typename Isolate>
|
||||
HandleFor<Isolate, BytecodeArray> BytecodeArrayBuilder::ToBytecodeArray(
|
||||
Isolate* isolate) {
|
||||
DCHECK(RemainderOfBlockIsDead());
|
||||
DCHECK(!bytecode_generated_);
|
||||
bytecode_generated_ = true;
|
||||
@ -93,25 +96,41 @@ Handle<BytecodeArray> BytecodeArrayBuilder::ToBytecodeArray(Isolate* isolate) {
|
||||
register_count = register_optimizer_->maxiumum_register_index() + 1;
|
||||
}
|
||||
|
||||
Handle<ByteArray> handler_table =
|
||||
HandleFor<Isolate, ByteArray> handler_table =
|
||||
handler_table_builder()->ToHandlerTable(isolate);
|
||||
return bytecode_array_writer_.ToBytecodeArray(
|
||||
isolate, register_count, parameter_count(), handler_table);
|
||||
}
|
||||
|
||||
template EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
|
||||
Handle<BytecodeArray> BytecodeArrayBuilder::ToBytecodeArray(
|
||||
Isolate* isolate);
|
||||
template EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
|
||||
OffThreadHandle<BytecodeArray> BytecodeArrayBuilder::ToBytecodeArray(
|
||||
OffThreadIsolate* isolate);
|
||||
|
||||
#ifdef DEBUG
|
||||
int BytecodeArrayBuilder::CheckBytecodeMatches(Handle<BytecodeArray> bytecode) {
|
||||
int BytecodeArrayBuilder::CheckBytecodeMatches(BytecodeArray bytecode) {
|
||||
DisallowHeapAllocation no_gc;
|
||||
return bytecode_array_writer_.CheckBytecodeMatches(bytecode);
|
||||
}
|
||||
#endif
|
||||
|
||||
Handle<ByteArray> BytecodeArrayBuilder::ToSourcePositionTable(
|
||||
template <typename Isolate>
|
||||
HandleFor<Isolate, ByteArray> BytecodeArrayBuilder::ToSourcePositionTable(
|
||||
Isolate* isolate) {
|
||||
DCHECK(RemainderOfBlockIsDead());
|
||||
|
||||
return bytecode_array_writer_.ToSourcePositionTable(isolate);
|
||||
}
|
||||
|
||||
template EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
|
||||
Handle<ByteArray> BytecodeArrayBuilder::ToSourcePositionTable(
|
||||
Isolate* isolate);
|
||||
template EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
|
||||
OffThreadHandle<ByteArray> BytecodeArrayBuilder::ToSourcePositionTable(
|
||||
OffThreadIsolate* isolate);
|
||||
|
||||
BytecodeSourceInfo BytecodeArrayBuilder::CurrentSourcePosition(
|
||||
Bytecode bytecode) {
|
||||
BytecodeSourceInfo source_position;
|
||||
@ -1549,8 +1568,8 @@ size_t BytecodeArrayBuilder::AllocateDeferredConstantPoolEntry() {
|
||||
return constant_array_builder()->InsertDeferred();
|
||||
}
|
||||
|
||||
void BytecodeArrayBuilder::SetDeferredConstantPoolEntry(size_t entry,
|
||||
Handle<Object> object) {
|
||||
void BytecodeArrayBuilder::SetDeferredConstantPoolEntry(
|
||||
size_t entry, HandleOrOffThreadHandle<Object> object) {
|
||||
constant_array_builder()->SetDeferredAt(entry, object);
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include "src/ast/ast.h"
|
||||
#include "src/base/compiler-specific.h"
|
||||
#include "src/base/export-template.h"
|
||||
#include "src/common/globals.h"
|
||||
#include "src/interpreter/bytecode-array-writer.h"
|
||||
#include "src/interpreter/bytecode-flags.h"
|
||||
@ -42,11 +43,15 @@ class V8_EXPORT_PRIVATE BytecodeArrayBuilder final {
|
||||
SourcePositionTableBuilder::RecordingMode source_position_mode =
|
||||
SourcePositionTableBuilder::RECORD_SOURCE_POSITIONS);
|
||||
|
||||
Handle<BytecodeArray> ToBytecodeArray(Isolate* isolate);
|
||||
Handle<ByteArray> ToSourcePositionTable(Isolate* isolate);
|
||||
template <typename Isolate>
|
||||
EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE)
|
||||
HandleFor<Isolate, BytecodeArray> ToBytecodeArray(Isolate* isolate);
|
||||
template <typename Isolate>
|
||||
EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE)
|
||||
HandleFor<Isolate, ByteArray> ToSourcePositionTable(Isolate* isolate);
|
||||
|
||||
#ifdef DEBUG
|
||||
int CheckBytecodeMatches(Handle<BytecodeArray> bytecode);
|
||||
int CheckBytecodeMatches(BytecodeArray bytecode);
|
||||
#endif
|
||||
|
||||
// Get the number of parameters expected by function.
|
||||
@ -498,7 +503,8 @@ class V8_EXPORT_PRIVATE BytecodeArrayBuilder final {
|
||||
// Allocates a slot in the constant pool which can later be set.
|
||||
size_t AllocateDeferredConstantPoolEntry();
|
||||
// Sets the deferred value into an allocated constant pool entry.
|
||||
void SetDeferredConstantPoolEntry(size_t entry, Handle<Object> object);
|
||||
void SetDeferredConstantPoolEntry(size_t entry,
|
||||
HandleOrOffThreadHandle<Object> object);
|
||||
|
||||
void InitializeReturnPosition(FunctionLiteral* literal);
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "src/interpreter/bytecode-array-writer.h"
|
||||
|
||||
#include "src/api/api-inl.h"
|
||||
#include "src/heap/off-thread-factory-inl.h"
|
||||
#include "src/interpreter/bytecode-jump-table.h"
|
||||
#include "src/interpreter/bytecode-label.h"
|
||||
#include "src/interpreter/bytecode-node.h"
|
||||
@ -36,43 +37,63 @@ BytecodeArrayWriter::BytecodeArrayWriter(
|
||||
bytecodes_.reserve(512); // Derived via experimentation.
|
||||
}
|
||||
|
||||
Handle<BytecodeArray> BytecodeArrayWriter::ToBytecodeArray(
|
||||
template <typename Isolate>
|
||||
HandleFor<Isolate, BytecodeArray> BytecodeArrayWriter::ToBytecodeArray(
|
||||
Isolate* isolate, int register_count, int parameter_count,
|
||||
Handle<ByteArray> handler_table) {
|
||||
HandleFor<Isolate, ByteArray> handler_table) {
|
||||
DCHECK_EQ(0, unbound_jumps_);
|
||||
|
||||
int bytecode_size = static_cast<int>(bytecodes()->size());
|
||||
int frame_size = register_count * kSystemPointerSize;
|
||||
Handle<FixedArray> constant_pool =
|
||||
HandleFor<Isolate, FixedArray> constant_pool =
|
||||
constant_array_builder()->ToFixedArray(isolate);
|
||||
Handle<BytecodeArray> bytecode_array = isolate->factory()->NewBytecodeArray(
|
||||
bytecode_size, &bytecodes()->front(), frame_size, parameter_count,
|
||||
constant_pool);
|
||||
HandleFor<Isolate, BytecodeArray> bytecode_array =
|
||||
isolate->factory()->NewBytecodeArray(bytecode_size, &bytecodes()->front(),
|
||||
frame_size, parameter_count,
|
||||
constant_pool);
|
||||
bytecode_array->set_handler_table(*handler_table);
|
||||
return bytecode_array;
|
||||
}
|
||||
|
||||
Handle<ByteArray> BytecodeArrayWriter::ToSourcePositionTable(Isolate* isolate) {
|
||||
template EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
|
||||
Handle<BytecodeArray> BytecodeArrayWriter::ToBytecodeArray(
|
||||
Isolate* isolate, int register_count, int parameter_count,
|
||||
Handle<ByteArray> handler_table);
|
||||
template EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
|
||||
OffThreadHandle<BytecodeArray> BytecodeArrayWriter::ToBytecodeArray(
|
||||
OffThreadIsolate* isolate, int register_count, int parameter_count,
|
||||
OffThreadHandle<ByteArray> handler_table);
|
||||
|
||||
template <typename Isolate>
|
||||
HandleFor<Isolate, ByteArray> BytecodeArrayWriter::ToSourcePositionTable(
|
||||
Isolate* isolate) {
|
||||
DCHECK(!source_position_table_builder_.Lazy());
|
||||
Handle<ByteArray> source_position_table =
|
||||
HandleFor<Isolate, ByteArray> source_position_table =
|
||||
source_position_table_builder_.Omit()
|
||||
? ReadOnlyRoots(isolate).empty_byte_array_handle()
|
||||
? isolate->factory()->empty_byte_array()
|
||||
: source_position_table_builder_.ToSourcePositionTable(isolate);
|
||||
return source_position_table;
|
||||
}
|
||||
|
||||
template EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
|
||||
Handle<ByteArray> BytecodeArrayWriter::ToSourcePositionTable(
|
||||
Isolate* isolate);
|
||||
template EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
|
||||
OffThreadHandle<ByteArray> BytecodeArrayWriter::ToSourcePositionTable(
|
||||
OffThreadIsolate* isolate);
|
||||
|
||||
#ifdef DEBUG
|
||||
int BytecodeArrayWriter::CheckBytecodeMatches(Handle<BytecodeArray> bytecode) {
|
||||
int BytecodeArrayWriter::CheckBytecodeMatches(BytecodeArray bytecode) {
|
||||
int mismatches = false;
|
||||
int bytecode_size = static_cast<int>(bytecodes()->size());
|
||||
const byte* bytecode_ptr = &bytecodes()->front();
|
||||
if (bytecode_size != bytecode->length()) mismatches = true;
|
||||
if (bytecode_size != bytecode.length()) mismatches = true;
|
||||
|
||||
// If there's a mismatch only in the length of the bytecode (very unlikely)
|
||||
// then the first mismatch will be the first extra bytecode.
|
||||
int first_mismatch = std::min(bytecode_size, bytecode->length());
|
||||
int first_mismatch = std::min(bytecode_size, bytecode.length());
|
||||
for (int i = 0; i < first_mismatch; ++i) {
|
||||
if (bytecode_ptr[i] != bytecode->get(i)) {
|
||||
if (bytecode_ptr[i] != bytecode.get(i)) {
|
||||
mismatches = true;
|
||||
first_mismatch = i;
|
||||
break;
|
||||
|
@ -53,15 +53,19 @@ class V8_EXPORT_PRIVATE BytecodeArrayWriter final {
|
||||
|
||||
void SetFunctionEntrySourcePosition(int position);
|
||||
|
||||
Handle<BytecodeArray> ToBytecodeArray(Isolate* isolate, int register_count,
|
||||
int parameter_count,
|
||||
Handle<ByteArray> handler_table);
|
||||
template <typename Isolate>
|
||||
EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE)
|
||||
HandleFor<Isolate, BytecodeArray> ToBytecodeArray(
|
||||
Isolate* isolate, int register_count, int parameter_count,
|
||||
HandleFor<Isolate, ByteArray> handler_table);
|
||||
|
||||
Handle<ByteArray> ToSourcePositionTable(Isolate* isolate);
|
||||
template <typename Isolate>
|
||||
EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE)
|
||||
HandleFor<Isolate, ByteArray> ToSourcePositionTable(Isolate* isolate);
|
||||
|
||||
#ifdef DEBUG
|
||||
// Returns -1 if they match or the offset of the first mismatching byte.
|
||||
int CheckBytecodeMatches(Handle<BytecodeArray> bytecode);
|
||||
int CheckBytecodeMatches(BytecodeArray bytecode);
|
||||
#endif
|
||||
|
||||
bool RemainderOfBlockIsDead() const { return exit_seen_in_block_; }
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "src/interpreter/bytecode-register.h"
|
||||
#include "src/interpreter/control-flow-builders.h"
|
||||
#include "src/logging/log.h"
|
||||
#include "src/logging/off-thread-logger.h"
|
||||
#include "src/objects/debug-objects.h"
|
||||
#include "src/objects/literal-objects-inl.h"
|
||||
#include "src/objects/objects-inl.h"
|
||||
@ -728,13 +729,13 @@ class BytecodeGenerator::TestResultScope final : public ExpressionResultScope {
|
||||
// Used to build a list of toplevel declaration data.
|
||||
class BytecodeGenerator::TopLevelDeclarationsBuilder final : public ZoneObject {
|
||||
public:
|
||||
Handle<FixedArray> AllocateDeclarations(UnoptimizedCompilationInfo* info,
|
||||
BytecodeGenerator* generator,
|
||||
Handle<Script> script,
|
||||
Isolate* isolate) {
|
||||
template <typename Isolate>
|
||||
HandleFor<Isolate, FixedArray> AllocateDeclarations(
|
||||
UnoptimizedCompilationInfo* info, BytecodeGenerator* generator,
|
||||
HandleFor<Isolate, Script> script, Isolate* isolate) {
|
||||
DCHECK(has_constant_pool_entry_);
|
||||
|
||||
Handle<FixedArray> data =
|
||||
HandleFor<Isolate, FixedArray> data =
|
||||
isolate->factory()->NewFixedArray(entry_slots_, AllocationType::kOld);
|
||||
|
||||
int array_index = 0;
|
||||
@ -748,11 +749,11 @@ class BytecodeGenerator::TopLevelDeclarationsBuilder final : public ZoneObject {
|
||||
#endif
|
||||
if (decl->IsFunctionDeclaration()) {
|
||||
FunctionLiteral* f = static_cast<FunctionDeclaration*>(decl)->fun();
|
||||
Handle<Object> sfi(
|
||||
HandleFor<Isolate, SharedFunctionInfo> sfi(
|
||||
Compiler::GetSharedFunctionInfo(f, script, isolate));
|
||||
// Return a null handle if any initial values can't be created. Caller
|
||||
// will set stack overflow.
|
||||
if (sfi.is_null()) return Handle<FixedArray>();
|
||||
if (sfi.is_null()) return HandleFor<Isolate, FixedArray>();
|
||||
data->set(array_index++, *sfi);
|
||||
int literal_index = generator->GetCachedCreateClosureSlot(f);
|
||||
data->set(array_index++, Smi::FromInt(literal_index));
|
||||
@ -777,11 +778,11 @@ class BytecodeGenerator::TopLevelDeclarationsBuilder final : public ZoneObject {
|
||||
DCHECK_EQ(start + kGlobalVariableDeclarationSize, array_index);
|
||||
} else {
|
||||
FunctionLiteral* f = static_cast<FunctionDeclaration*>(decl)->fun();
|
||||
Handle<Object> sfi(
|
||||
HandleFor<Isolate, SharedFunctionInfo> sfi(
|
||||
Compiler::GetSharedFunctionInfo(f, script, isolate));
|
||||
// Return a null handle if any initial values can't be created. Caller
|
||||
// will set stack overflow.
|
||||
if (sfi.is_null()) return Handle<FixedArray>();
|
||||
if (sfi.is_null()) return HandleFor<Isolate, FixedArray>();
|
||||
data->set(array_index++, *sfi);
|
||||
int literal_index = generator->GetCachedCreateClosureSlot(f);
|
||||
data->set(array_index++, Smi::FromInt(literal_index));
|
||||
@ -1049,29 +1050,55 @@ BytecodeGenerator::BytecodeGenerator(
|
||||
}
|
||||
}
|
||||
|
||||
Handle<BytecodeArray> BytecodeGenerator::FinalizeBytecode(
|
||||
Isolate* isolate, Handle<Script> script) {
|
||||
namespace {
|
||||
|
||||
template <typename Isolate>
|
||||
struct NullContextScopeHelper;
|
||||
|
||||
template <>
|
||||
struct NullContextScopeHelper<Isolate> {
|
||||
using Type = NullContextScope;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct NullContextScopeHelper<OffThreadIsolate> {
|
||||
class DummyNullContextScope {
|
||||
public:
|
||||
explicit DummyNullContextScope(OffThreadIsolate*) {}
|
||||
};
|
||||
using Type = DummyNullContextScope;
|
||||
};
|
||||
|
||||
template <typename Isolate>
|
||||
using NullContextScopeFor = typename NullContextScopeHelper<Isolate>::Type;
|
||||
|
||||
} // namespace
|
||||
|
||||
template <typename Isolate>
|
||||
HandleFor<Isolate, BytecodeArray> BytecodeGenerator::FinalizeBytecode(
|
||||
Isolate* isolate, HandleFor<Isolate, Script> script) {
|
||||
DCHECK_EQ(ThreadId::Current(), isolate->thread_id());
|
||||
#ifdef DEBUG
|
||||
// Unoptimized compilation should be context-independent. Verify that we don't
|
||||
// access the native context by nulling it out during finalization.
|
||||
NullContextScope null_context_scope(isolate);
|
||||
NullContextScopeFor<Isolate> null_context_scope(isolate);
|
||||
#endif
|
||||
|
||||
AllocateDeferredConstants(isolate, script);
|
||||
|
||||
if (block_coverage_builder_) {
|
||||
info()->set_coverage_info(
|
||||
isolate->factory()->NewCoverageInfo(block_coverage_builder_->slots()));
|
||||
HandleFor<Isolate, CoverageInfo> coverage_info =
|
||||
isolate->factory()->NewCoverageInfo(block_coverage_builder_->slots());
|
||||
info()->set_coverage_info(coverage_info);
|
||||
if (FLAG_trace_block_coverage) {
|
||||
StdoutStream os;
|
||||
info()->coverage_info()->CoverageInfoPrint(
|
||||
os, info()->literal()->GetDebugName());
|
||||
coverage_info->CoverageInfoPrint(os, info()->literal()->GetDebugName());
|
||||
}
|
||||
}
|
||||
|
||||
if (HasStackOverflow()) return Handle<BytecodeArray>();
|
||||
Handle<BytecodeArray> bytecode_array = builder()->ToBytecodeArray(isolate);
|
||||
if (HasStackOverflow()) return HandleFor<Isolate, BytecodeArray>();
|
||||
HandleFor<Isolate, BytecodeArray> bytecode_array =
|
||||
builder()->ToBytecodeArray(isolate);
|
||||
|
||||
if (incoming_new_target_or_generator_.is_valid()) {
|
||||
bytecode_array->set_incoming_new_target_or_generator_register(
|
||||
@ -1081,38 +1108,51 @@ Handle<BytecodeArray> BytecodeGenerator::FinalizeBytecode(
|
||||
return bytecode_array;
|
||||
}
|
||||
|
||||
Handle<ByteArray> BytecodeGenerator::FinalizeSourcePositionTable(
|
||||
template Handle<BytecodeArray> BytecodeGenerator::FinalizeBytecode(
|
||||
Isolate* isolate, Handle<Script> script);
|
||||
template OffThreadHandle<BytecodeArray> BytecodeGenerator::FinalizeBytecode(
|
||||
OffThreadIsolate* isolate, OffThreadHandle<Script> script);
|
||||
|
||||
template <typename Isolate>
|
||||
HandleFor<Isolate, ByteArray> BytecodeGenerator::FinalizeSourcePositionTable(
|
||||
Isolate* isolate) {
|
||||
DCHECK_EQ(ThreadId::Current(), isolate->thread_id());
|
||||
#ifdef DEBUG
|
||||
// Unoptimized compilation should be context-independent. Verify that we don't
|
||||
// access the native context by nulling it out during finalization.
|
||||
NullContextScope null_context_scope(isolate);
|
||||
NullContextScopeFor<Isolate> null_context_scope(isolate);
|
||||
#endif
|
||||
|
||||
Handle<ByteArray> source_position_table =
|
||||
HandleFor<Isolate, ByteArray> source_position_table =
|
||||
builder()->ToSourcePositionTable(isolate);
|
||||
|
||||
LOG_CODE_EVENT(isolate,
|
||||
CodeLinePosInfoRecordEvent(
|
||||
info_->bytecode_array()->GetFirstBytecodeAddress(),
|
||||
*source_position_table));
|
||||
LOG_CODE_EVENT(
|
||||
isolate, CodeLinePosInfoRecordEvent(
|
||||
info_->bytecode_array<Isolate>()->GetFirstBytecodeAddress(),
|
||||
*source_position_table));
|
||||
|
||||
return source_position_table;
|
||||
}
|
||||
|
||||
template Handle<ByteArray> BytecodeGenerator::FinalizeSourcePositionTable(
|
||||
Isolate* isolate);
|
||||
template OffThreadHandle<ByteArray>
|
||||
BytecodeGenerator::FinalizeSourcePositionTable(OffThreadIsolate* isolate);
|
||||
|
||||
#ifdef DEBUG
|
||||
int BytecodeGenerator::CheckBytecodeMatches(Handle<BytecodeArray> bytecode) {
|
||||
int BytecodeGenerator::CheckBytecodeMatches(BytecodeArray bytecode) {
|
||||
return builder()->CheckBytecodeMatches(bytecode);
|
||||
}
|
||||
#endif
|
||||
|
||||
void BytecodeGenerator::AllocateDeferredConstants(Isolate* isolate,
|
||||
Handle<Script> script) {
|
||||
template <typename Isolate>
|
||||
void BytecodeGenerator::AllocateDeferredConstants(
|
||||
Isolate* isolate, HandleFor<Isolate, Script> script) {
|
||||
if (top_level_builder()->has_top_level_declaration()) {
|
||||
// Build global declaration pair array.
|
||||
Handle<FixedArray> declarations = top_level_builder()->AllocateDeclarations(
|
||||
info(), this, script, isolate);
|
||||
HandleFor<Isolate, FixedArray> declarations =
|
||||
top_level_builder()->AllocateDeclarations(info(), this, script,
|
||||
isolate);
|
||||
if (declarations.is_null()) return SetStackOverflow();
|
||||
builder()->SetDeferredConstantPoolEntry(
|
||||
top_level_builder()->constant_pool_entry(), declarations);
|
||||
@ -1121,7 +1161,7 @@ void BytecodeGenerator::AllocateDeferredConstants(Isolate* isolate,
|
||||
// Find or build shared function infos.
|
||||
for (std::pair<FunctionLiteral*, size_t> literal : function_literals_) {
|
||||
FunctionLiteral* expr = literal.first;
|
||||
Handle<SharedFunctionInfo> shared_info =
|
||||
HandleFor<Isolate, SharedFunctionInfo> shared_info =
|
||||
Compiler::GetSharedFunctionInfo(expr, script, isolate);
|
||||
if (shared_info.is_null()) return SetStackOverflow();
|
||||
builder()->SetDeferredConstantPoolEntry(literal.second, shared_info);
|
||||
@ -1130,6 +1170,9 @@ void BytecodeGenerator::AllocateDeferredConstants(Isolate* isolate,
|
||||
// Find or build shared function infos for the native function templates.
|
||||
for (std::pair<NativeFunctionLiteral*, size_t> literal :
|
||||
native_function_literals_) {
|
||||
// This should only happen for main-thread compilations.
|
||||
DCHECK((std::is_same<Isolate, v8::internal::Isolate>::value));
|
||||
|
||||
NativeFunctionLiteral* expr = literal.first;
|
||||
v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
|
||||
|
||||
@ -1139,7 +1182,7 @@ void BytecodeGenerator::AllocateDeferredConstants(Isolate* isolate,
|
||||
v8_isolate, Utils::ToLocal(expr->name()));
|
||||
DCHECK(!info.IsEmpty());
|
||||
|
||||
Handle<SharedFunctionInfo> shared_info =
|
||||
HandleFor<Isolate, SharedFunctionInfo> shared_info =
|
||||
FunctionTemplateInfo::GetOrCreateSharedFunctionInfo(
|
||||
isolate, Utils::OpenHandle(*info), expr->name());
|
||||
DCHECK(!shared_info.is_null());
|
||||
@ -1152,7 +1195,7 @@ void BytecodeGenerator::AllocateDeferredConstants(Isolate* isolate,
|
||||
if (object_literal->properties_count() > 0) {
|
||||
// If constant properties is an empty fixed array, we've already added it
|
||||
// to the constant pool when visiting the object literal.
|
||||
Handle<ObjectBoilerplateDescription> constant_properties =
|
||||
HandleFor<Isolate, ObjectBoilerplateDescription> constant_properties =
|
||||
object_literal->GetOrBuildBoilerplateDescription(isolate);
|
||||
|
||||
builder()->SetDeferredConstantPoolEntry(literal.second,
|
||||
@ -1163,7 +1206,7 @@ void BytecodeGenerator::AllocateDeferredConstants(Isolate* isolate,
|
||||
// Build array literal constant elements
|
||||
for (std::pair<ArrayLiteral*, size_t> literal : array_literals_) {
|
||||
ArrayLiteral* array_literal = literal.first;
|
||||
Handle<ArrayBoilerplateDescription> constant_elements =
|
||||
HandleFor<Isolate, ArrayBoilerplateDescription> constant_elements =
|
||||
array_literal->GetOrBuildBoilerplateDescription(isolate);
|
||||
builder()->SetDeferredConstantPoolEntry(literal.second, constant_elements);
|
||||
}
|
||||
@ -1171,7 +1214,7 @@ void BytecodeGenerator::AllocateDeferredConstants(Isolate* isolate,
|
||||
// Build class literal boilerplates.
|
||||
for (std::pair<ClassLiteral*, size_t> literal : class_literals_) {
|
||||
ClassLiteral* class_literal = literal.first;
|
||||
Handle<ClassBoilerplate> class_boilerplate =
|
||||
HandleFor<Isolate, ClassBoilerplate> class_boilerplate =
|
||||
ClassBoilerplate::BuildClassBoilerplate(isolate, class_literal);
|
||||
builder()->SetDeferredConstantPoolEntry(literal.second, class_boilerplate);
|
||||
}
|
||||
@ -1179,12 +1222,17 @@ void BytecodeGenerator::AllocateDeferredConstants(Isolate* isolate,
|
||||
// Build template literals.
|
||||
for (std::pair<GetTemplateObject*, size_t> literal : template_objects_) {
|
||||
GetTemplateObject* get_template_object = literal.first;
|
||||
Handle<TemplateObjectDescription> description =
|
||||
HandleFor<Isolate, TemplateObjectDescription> description =
|
||||
get_template_object->GetOrBuildDescription(isolate);
|
||||
builder()->SetDeferredConstantPoolEntry(literal.second, description);
|
||||
}
|
||||
}
|
||||
|
||||
template void BytecodeGenerator::AllocateDeferredConstants(
|
||||
Isolate* isolate, Handle<Script> script);
|
||||
template void BytecodeGenerator::AllocateDeferredConstants(
|
||||
OffThreadIsolate* isolate, OffThreadHandle<Script> script);
|
||||
|
||||
namespace {
|
||||
bool NeedsContextInitialization(DeclarationScope* scope) {
|
||||
return scope->NeedsContext() && !scope->is_script_scope() &&
|
||||
|
@ -37,12 +37,14 @@ class BytecodeGenerator final : public AstVisitor<BytecodeGenerator> {
|
||||
std::vector<FunctionLiteral*>* eager_inner_literals);
|
||||
|
||||
void GenerateBytecode(uintptr_t stack_limit);
|
||||
Handle<BytecodeArray> FinalizeBytecode(Isolate* isolate,
|
||||
Handle<Script> script);
|
||||
Handle<ByteArray> FinalizeSourcePositionTable(Isolate* isolate);
|
||||
template <typename Isolate>
|
||||
HandleFor<Isolate, BytecodeArray> FinalizeBytecode(
|
||||
Isolate* isolate, HandleFor<Isolate, Script> script);
|
||||
template <typename Isolate>
|
||||
HandleFor<Isolate, ByteArray> FinalizeSourcePositionTable(Isolate* isolate);
|
||||
|
||||
#ifdef DEBUG
|
||||
int CheckBytecodeMatches(Handle<BytecodeArray> bytecode);
|
||||
int CheckBytecodeMatches(BytecodeArray bytecode);
|
||||
#endif
|
||||
|
||||
#define DECLARE_VISIT(type) void Visit##type(type* node);
|
||||
@ -161,7 +163,9 @@ class BytecodeGenerator final : public AstVisitor<BytecodeGenerator> {
|
||||
};
|
||||
|
||||
void GenerateBytecodeBody();
|
||||
void AllocateDeferredConstants(Isolate* isolate, Handle<Script> script);
|
||||
template <typename Isolate>
|
||||
void AllocateDeferredConstants(Isolate* isolate,
|
||||
HandleFor<Isolate, Script> script);
|
||||
|
||||
DEFINE_AST_VISITOR_SUBCLASS_MEMBERS();
|
||||
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "src/ast/scopes.h"
|
||||
#include "src/base/functional.h"
|
||||
#include "src/execution/isolate.h"
|
||||
#include "src/heap/off-thread-factory-inl.h"
|
||||
#include "src/objects/objects-inl.h"
|
||||
|
||||
namespace v8 {
|
||||
@ -64,6 +65,7 @@ const ConstantArrayBuilder::Entry& ConstantArrayBuilder::ConstantArraySlice::At(
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
template <typename Isolate>
|
||||
void ConstantArrayBuilder::ConstantArraySlice::CheckAllElementsAreUnique(
|
||||
Isolate* isolate) const {
|
||||
std::set<Smi> smis;
|
||||
@ -91,7 +93,8 @@ void ConstantArrayBuilder::ConstantArraySlice::CheckAllElementsAreUnique(
|
||||
duplicate = !scopes.insert(entry.scope_).second;
|
||||
break;
|
||||
case Entry::Tag::kHandle:
|
||||
duplicate = !deferred_objects.insert(*entry.handle_).second;
|
||||
duplicate =
|
||||
!deferred_objects.insert(*entry.handle_.get<Isolate>()).second;
|
||||
break;
|
||||
case Entry::Tag::kDeferred:
|
||||
UNREACHABLE(); // Should be kHandle at this point.
|
||||
@ -166,20 +169,31 @@ ConstantArrayBuilder::ConstantArraySlice* ConstantArrayBuilder::IndexToSlice(
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
MaybeHandle<Object> ConstantArrayBuilder::At(size_t index,
|
||||
Isolate* isolate) const {
|
||||
template <typename Isolate>
|
||||
MaybeHandleFor<Isolate, Object> ConstantArrayBuilder::At(
|
||||
size_t index, Isolate* isolate) const {
|
||||
const ConstantArraySlice* slice = IndexToSlice(index);
|
||||
DCHECK_LT(index, slice->capacity());
|
||||
if (index < slice->start_index() + slice->size()) {
|
||||
const Entry& entry = slice->At(index);
|
||||
if (!entry.IsDeferred()) return entry.ToHandle(isolate);
|
||||
}
|
||||
return MaybeHandle<Object>();
|
||||
return MaybeHandleFor<Isolate, Object>();
|
||||
}
|
||||
|
||||
Handle<FixedArray> ConstantArrayBuilder::ToFixedArray(Isolate* isolate) {
|
||||
Handle<FixedArray> fixed_array = isolate->factory()->NewFixedArrayWithHoles(
|
||||
static_cast<int>(size()), AllocationType::kOld);
|
||||
template EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
|
||||
MaybeHandle<Object> ConstantArrayBuilder::At(size_t index,
|
||||
Isolate* isolate) const;
|
||||
template EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
|
||||
OffThreadHandle<Object> ConstantArrayBuilder::At(
|
||||
size_t index, OffThreadIsolate* isolate) const;
|
||||
|
||||
template <typename Isolate>
|
||||
HandleFor<Isolate, FixedArray> ConstantArrayBuilder::ToFixedArray(
|
||||
Isolate* isolate) {
|
||||
HandleFor<Isolate, FixedArray> fixed_array =
|
||||
isolate->factory()->NewFixedArrayWithHoles(static_cast<int>(size()),
|
||||
AllocationType::kOld);
|
||||
int array_index = 0;
|
||||
for (const ConstantArraySlice* slice : idx_slice_) {
|
||||
DCHECK_EQ(slice->reserved(), 0);
|
||||
@ -192,7 +206,7 @@ Handle<FixedArray> ConstantArrayBuilder::ToFixedArray(Isolate* isolate) {
|
||||
#endif
|
||||
// Copy objects from slice into array.
|
||||
for (size_t i = 0; i < slice->size(); ++i) {
|
||||
Handle<Object> value =
|
||||
HandleFor<Isolate, Object> value =
|
||||
slice->At(slice->start_index() + i).ToHandle(isolate);
|
||||
fixed_array->set(array_index++, *value);
|
||||
}
|
||||
@ -207,6 +221,12 @@ Handle<FixedArray> ConstantArrayBuilder::ToFixedArray(Isolate* isolate) {
|
||||
return fixed_array;
|
||||
}
|
||||
|
||||
template EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
|
||||
Handle<FixedArray> ConstantArrayBuilder::ToFixedArray(Isolate* isolate);
|
||||
template EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
|
||||
OffThreadHandle<FixedArray> ConstantArrayBuilder::ToFixedArray(
|
||||
OffThreadIsolate* isolate);
|
||||
|
||||
size_t ConstantArrayBuilder::Insert(Smi smi) {
|
||||
auto entry = smi_map_.find(smi);
|
||||
if (entry == smi_map_.end()) {
|
||||
@ -306,7 +326,8 @@ size_t ConstantArrayBuilder::InsertJumpTable(size_t size) {
|
||||
return AllocateIndexArray(Entry::UninitializedJumpTableSmi(), size);
|
||||
}
|
||||
|
||||
void ConstantArrayBuilder::SetDeferredAt(size_t index, Handle<Object> object) {
|
||||
void ConstantArrayBuilder::SetDeferredAt(
|
||||
size_t index, HandleOrOffThreadHandle<Object> object) {
|
||||
ConstantArraySlice* slice = IndexToSlice(index);
|
||||
return slice->At(index).SetDeferred(object);
|
||||
}
|
||||
@ -362,7 +383,9 @@ void ConstantArrayBuilder::DiscardReservedEntry(OperandSize operand_size) {
|
||||
OperandSizeToSlice(operand_size)->Unreserve();
|
||||
}
|
||||
|
||||
Handle<Object> ConstantArrayBuilder::Entry::ToHandle(Isolate* isolate) const {
|
||||
template <typename Isolate>
|
||||
HandleFor<Isolate, Object> ConstantArrayBuilder::Entry::ToHandle(
|
||||
Isolate* isolate) const {
|
||||
switch (tag_) {
|
||||
case Tag::kDeferred:
|
||||
// We shouldn't have any deferred entries by now.
|
||||
@ -378,7 +401,8 @@ Handle<Object> ConstantArrayBuilder::Entry::ToHandle(Isolate* isolate) const {
|
||||
case Tag::kRawString:
|
||||
return raw_string_->string();
|
||||
case Tag::kHeapNumber:
|
||||
return isolate->factory()->NewNumber<AllocationType::kOld>(heap_number_);
|
||||
return isolate->factory()->template NewNumber<AllocationType::kOld>(
|
||||
heap_number_);
|
||||
case Tag::kBigInt:
|
||||
// This should never fail: the parser will never create a BigInt
|
||||
// literal that cannot be allocated.
|
||||
@ -394,6 +418,11 @@ Handle<Object> ConstantArrayBuilder::Entry::ToHandle(Isolate* isolate) const {
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
template Handle<Object> ConstantArrayBuilder::Entry::ToHandle(
|
||||
Isolate* isolate) const;
|
||||
template OffThreadHandle<Object> ConstantArrayBuilder::Entry::ToHandle(
|
||||
OffThreadIsolate* isolate) const;
|
||||
|
||||
} // namespace interpreter
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include "src/ast/ast-value-factory.h"
|
||||
#include "src/common/globals.h"
|
||||
#include "src/handles/handles.h"
|
||||
#include "src/interpreter/bytecodes.h"
|
||||
#include "src/objects/smi.h"
|
||||
#include "src/utils/identity-map.h"
|
||||
@ -52,12 +53,16 @@ class V8_EXPORT_PRIVATE ConstantArrayBuilder final {
|
||||
explicit ConstantArrayBuilder(Zone* zone);
|
||||
|
||||
// Generate a fixed array of constant handles based on inserted objects.
|
||||
Handle<FixedArray> ToFixedArray(Isolate* isolate);
|
||||
template <typename Isolate>
|
||||
EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE)
|
||||
HandleFor<Isolate, FixedArray> ToFixedArray(Isolate* isolate);
|
||||
|
||||
// Returns the object, as a handle in |isolate|, that is in the constant pool
|
||||
// array at index |index|. Returns null if there is no handle at this index.
|
||||
// Only expected to be used in tests.
|
||||
MaybeHandle<Object> At(size_t index, Isolate* isolate) const;
|
||||
template <typename Isolate>
|
||||
EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE)
|
||||
MaybeHandleFor<Isolate, Object> At(size_t index, Isolate* isolate) const;
|
||||
|
||||
// Returns the number of elements in the array.
|
||||
size_t size() const;
|
||||
@ -84,7 +89,7 @@ class V8_EXPORT_PRIVATE ConstantArrayBuilder final {
|
||||
size_t InsertJumpTable(size_t size);
|
||||
|
||||
// Sets the deferred value at |index| to |object|.
|
||||
void SetDeferredAt(size_t index, Handle<Object> object);
|
||||
void SetDeferredAt(size_t index, HandleOrOffThreadHandle<Object> object);
|
||||
|
||||
// Sets the jump table entry at |index| to |smi|. Note that |index| is the
|
||||
// constant pool index, not the switch case value.
|
||||
@ -138,7 +143,7 @@ class V8_EXPORT_PRIVATE ConstantArrayBuilder final {
|
||||
tag_ == Tag::kJumpTableSmi;
|
||||
}
|
||||
|
||||
void SetDeferred(Handle<Object> handle) {
|
||||
void SetDeferred(HandleOrOffThreadHandle<Object> handle) {
|
||||
DCHECK_EQ(tag_, Tag::kDeferred);
|
||||
tag_ = Tag::kHandle;
|
||||
handle_ = handle;
|
||||
@ -150,13 +155,14 @@ class V8_EXPORT_PRIVATE ConstantArrayBuilder final {
|
||||
smi_ = smi;
|
||||
}
|
||||
|
||||
Handle<Object> ToHandle(Isolate* isolate) const;
|
||||
template <typename Isolate>
|
||||
HandleFor<Isolate, Object> ToHandle(Isolate* isolate) const;
|
||||
|
||||
private:
|
||||
explicit Entry(Tag tag) : tag_(tag) {}
|
||||
|
||||
union {
|
||||
Handle<Object> handle_;
|
||||
HandleOrOffThreadHandle<Object> handle_;
|
||||
Smi smi_;
|
||||
double heap_number_;
|
||||
const AstRawString* raw_string_;
|
||||
@ -199,6 +205,7 @@ class V8_EXPORT_PRIVATE ConstantArrayBuilder final {
|
||||
const Entry& At(size_t index) const;
|
||||
|
||||
#if DEBUG
|
||||
template <typename Isolate>
|
||||
void CheckAllElementsAreUnique(Isolate* isolate) const;
|
||||
#endif
|
||||
|
||||
|
@ -15,10 +15,14 @@ namespace interpreter {
|
||||
|
||||
HandlerTableBuilder::HandlerTableBuilder(Zone* zone) : entries_(zone) {}
|
||||
|
||||
Handle<ByteArray> HandlerTableBuilder::ToHandlerTable(Isolate* isolate) {
|
||||
template <typename Isolate>
|
||||
HandleFor<Isolate, ByteArray> HandlerTableBuilder::ToHandlerTable(
|
||||
Isolate* isolate) {
|
||||
int handler_table_size = static_cast<int>(entries_.size());
|
||||
Handle<ByteArray> table_byte_array = isolate->factory()->NewByteArray(
|
||||
HandlerTable::LengthForRange(handler_table_size), AllocationType::kOld);
|
||||
HandleFor<Isolate, ByteArray> table_byte_array =
|
||||
isolate->factory()->NewByteArray(
|
||||
HandlerTable::LengthForRange(handler_table_size),
|
||||
AllocationType::kOld);
|
||||
HandlerTable table(*table_byte_array);
|
||||
for (int i = 0; i < handler_table_size; ++i) {
|
||||
Entry& entry = entries_[i];
|
||||
@ -31,6 +35,10 @@ Handle<ByteArray> HandlerTableBuilder::ToHandlerTable(Isolate* isolate) {
|
||||
return table_byte_array;
|
||||
}
|
||||
|
||||
template Handle<ByteArray> HandlerTableBuilder::ToHandlerTable(
|
||||
Isolate* isolate);
|
||||
template OffThreadHandle<ByteArray> HandlerTableBuilder::ToHandlerTable(
|
||||
OffThreadIsolate* isolate);
|
||||
|
||||
int HandlerTableBuilder::NewHandlerEntry() {
|
||||
int handler_id = static_cast<int>(entries_.size());
|
||||
|
@ -28,7 +28,8 @@ class V8_EXPORT_PRIVATE HandlerTableBuilder final {
|
||||
|
||||
// Builds the actual handler table by copying the current values into a heap
|
||||
// object. Any further mutations to the builder won't be reflected.
|
||||
Handle<ByteArray> ToHandlerTable(Isolate* isolate);
|
||||
template <typename Isolate>
|
||||
HandleFor<Isolate, ByteArray> ToHandlerTable(Isolate* isolate);
|
||||
|
||||
// Creates a new handler table entry and returns a {hander_id} identifying the
|
||||
// entry, so that it can be referenced by below setter functions.
|
||||
|
@ -173,7 +173,7 @@ InterpreterCompilationJob::Status InterpreterCompilationJob::ExecuteJobImpl() {
|
||||
#ifdef DEBUG
|
||||
void InterpreterCompilationJob::CheckAndPrintBytecodeMismatch(
|
||||
Isolate* isolate, Handle<Script> script, Handle<BytecodeArray> bytecode) {
|
||||
int first_mismatch = generator()->CheckBytecodeMatches(bytecode);
|
||||
int first_mismatch = generator()->CheckBytecodeMatches(*bytecode);
|
||||
if (first_mismatch >= 0) {
|
||||
parse_info()->ast_value_factory()->Internalize(isolate);
|
||||
DeclarationScope::AllocateScopeInfos(parse_info(), isolate);
|
||||
@ -214,7 +214,7 @@ InterpreterCompilationJob::Status InterpreterCompilationJob::FinalizeJobImpl(
|
||||
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
|
||||
"V8.CompileIgnitionFinalization");
|
||||
|
||||
Handle<BytecodeArray> bytecodes = compilation_info_.bytecode_array();
|
||||
Handle<BytecodeArray> bytecodes = compilation_info_.bytecode_array<Isolate>();
|
||||
if (bytecodes.is_null()) {
|
||||
bytecodes = generator()->FinalizeBytecode(
|
||||
isolate, handle(Script::cast(shared_info->script()), isolate));
|
||||
|
@ -11,7 +11,7 @@
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
// TODO(leszeks): Possibly add support for logging from off-thread.
|
||||
// TODO(leszeks): Add support for logging from off-thread.
|
||||
class OffThreadLogger {
|
||||
public:
|
||||
bool is_logging() const { return false; }
|
||||
@ -19,6 +19,10 @@ class OffThreadLogger {
|
||||
void ScriptEvent(Logger::ScriptEventType type, int script_id) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
void CodeLinePosInfoRecordEvent(Address code_start,
|
||||
ByteArray source_position_table) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "src/objects/literal-objects.h"
|
||||
|
||||
#include "src/ast/ast.h"
|
||||
#include "src/base/logging.h"
|
||||
#include "src/builtins/accessors.h"
|
||||
#include "src/execution/isolate.h"
|
||||
#include "src/heap/factory.h"
|
||||
@ -567,5 +568,11 @@ Handle<ClassBoilerplate> ClassBoilerplate::BuildClassBoilerplate(
|
||||
return scope.CloseAndEscape(class_boilerplate);
|
||||
}
|
||||
|
||||
OffThreadHandle<ClassBoilerplate> ClassBoilerplate::BuildClassBoilerplate(
|
||||
OffThreadIsolate* isolate, ClassLiteral* expr) {
|
||||
// TODO(leszeks): Add class boilerplate support to off-thread finalization.
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
@ -130,6 +130,9 @@ class ClassBoilerplate : public FixedArray {
|
||||
static Handle<ClassBoilerplate> BuildClassBoilerplate(Isolate* isolate,
|
||||
ClassLiteral* expr);
|
||||
|
||||
static OffThreadHandle<ClassBoilerplate> BuildClassBoilerplate(
|
||||
OffThreadIsolate* isolate, ClassLiteral* expr);
|
||||
|
||||
enum {
|
||||
kFlagsIndex,
|
||||
kClassPropertiesTemplateIndex,
|
||||
|
@ -4895,7 +4895,8 @@ Object Script::GetNameOrSourceURL() {
|
||||
return name();
|
||||
}
|
||||
|
||||
MaybeHandle<SharedFunctionInfo> Script::FindSharedFunctionInfo(
|
||||
template <typename Isolate>
|
||||
MaybeHandleFor<Isolate, SharedFunctionInfo> Script::FindSharedFunctionInfo(
|
||||
Isolate* isolate, const FunctionLiteral* fun) {
|
||||
CHECK_NE(fun->function_literal_id(), kFunctionLiteralIdInvalid);
|
||||
// If this check fails, the problem is most probably the function id
|
||||
@ -4907,10 +4908,14 @@ MaybeHandle<SharedFunctionInfo> Script::FindSharedFunctionInfo(
|
||||
HeapObject heap_object;
|
||||
if (!shared->GetHeapObject(&heap_object) ||
|
||||
heap_object.IsUndefined(isolate)) {
|
||||
return MaybeHandle<SharedFunctionInfo>();
|
||||
return MaybeHandleFor<Isolate, SharedFunctionInfo>();
|
||||
}
|
||||
return handle(SharedFunctionInfo::cast(heap_object), isolate);
|
||||
}
|
||||
template MaybeHandle<SharedFunctionInfo> Script::FindSharedFunctionInfo(
|
||||
Isolate* isolate, const FunctionLiteral* fun);
|
||||
template OffThreadHandle<SharedFunctionInfo> Script::FindSharedFunctionInfo(
|
||||
OffThreadIsolate* isolate, const FunctionLiteral* fun);
|
||||
|
||||
Script::Iterator::Iterator(Isolate* isolate)
|
||||
: iterator_(isolate->heap()->script_list()) {}
|
||||
|
@ -195,7 +195,8 @@ class Script : public Struct {
|
||||
|
||||
// Look through the list of existing shared function infos to find one
|
||||
// that matches the function literal. Return empty handle if not found.
|
||||
MaybeHandle<SharedFunctionInfo> FindSharedFunctionInfo(
|
||||
template <typename Isolate>
|
||||
MaybeHandleFor<Isolate, SharedFunctionInfo> FindSharedFunctionInfo(
|
||||
Isolate* isolate, const FunctionLiteral* fun);
|
||||
|
||||
// Iterate over all script objects on the heap.
|
||||
|
@ -120,6 +120,14 @@ class FunctionTemplateInfo
|
||||
static Handle<SharedFunctionInfo> GetOrCreateSharedFunctionInfo(
|
||||
Isolate* isolate, Handle<FunctionTemplateInfo> info,
|
||||
MaybeHandle<Name> maybe_name);
|
||||
|
||||
static OffThreadHandle<SharedFunctionInfo> GetOrCreateSharedFunctionInfo(
|
||||
OffThreadIsolate* isolate, Handle<FunctionTemplateInfo> info,
|
||||
Handle<Name> maybe_name) {
|
||||
// We don't support streaming compilation of scripts with natives, so we
|
||||
// don't need an off-thread implementation of this.
|
||||
UNREACHABLE();
|
||||
}
|
||||
// Returns parent function template or a null FunctionTemplateInfo.
|
||||
inline FunctionTemplateInfo GetParent(Isolate* isolate);
|
||||
// Returns true if |object| is an instance of this function template.
|
||||
|
Loading…
Reference in New Issue
Block a user