Commit b814c1d5 authored by Leszek Swirski's avatar Leszek Swirski Committed by Commit Bot

[offthread] Refactor out an OffThreadHeap

Refactors out the allocation and space merging parts of OffThreadFactory
into a new OffThreadHeap class. This allows a separation of concerns
between allocating/merging and initializing, and future-proofs the
factory code against off-thread allocation implementation changes (e.g.
LocalHeap).

Bug: chromium:1011762
Change-Id: I876906dbfd50f8aafe56af2e63e5fe35e4f7f8e9
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2157369
Auto-Submit: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: 's avatarUlan Degenbaev <ulan@chromium.org>
Reviewed-by: 's avatarIgor Sheludko <ishell@chromium.org>
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/heads/master@{#67270}
parent b39ee29d
......@@ -2433,6 +2433,8 @@ v8_source_set("v8_base_without_compiler") {
"src/heap/objects-visiting.h",
"src/heap/off-thread-factory.cc",
"src/heap/off-thread-factory.h",
"src/heap/off-thread-heap.cc",
"src/heap/off-thread-heap.h",
"src/heap/read-only-heap-inl.h",
"src/heap/read-only-heap.cc",
"src/heap/read-only-heap.h",
......
......@@ -19,6 +19,7 @@ include_rules = [
"+src/heap/local-heap.h",
"+src/heap/off-thread-factory-inl.h",
"+src/heap/off-thread-factory.h",
"+src/heap/off-thread-heap.h",
"+src/heap/read-only-heap-inl.h",
"+src/heap/read-only-heap.h",
"+src/heap/safepoint.h",
......
......@@ -14,8 +14,6 @@
#include "src/codegen/bailout-reason.h"
#include "src/codegen/label.h"
#include "src/common/globals.h"
#include "src/execution/isolate.h"
#include "src/execution/off-thread-isolate.h"
#include "src/heap/factory.h"
#include "src/objects/elements-kind.h"
#include "src/objects/function-syntax-kind.h"
......@@ -117,6 +115,9 @@ namespace internal {
EXPRESSION_NODE_LIST(V)
// Forward declarations
class Isolate;
class OffThreadIsolate;
class AstNode;
class AstNodeFactory;
class Declaration;
......
......@@ -2418,7 +2418,7 @@ Compiler::GetSharedFunctionInfoForStreamedScript(
Handle<SharedFunctionInfo> sfi(task->outer_function_sfi(), isolate);
Handle<Script> script(Script::cast(sfi->script()), isolate);
task->off_thread_isolate()->factory()->Publish(isolate);
task->off_thread_isolate()->Publish(isolate);
FixUpOffThreadAllocatedScript(isolate, script, source, script_details,
origin_options, NOT_NATIVES_CODE);
......
......@@ -13,11 +13,21 @@ namespace internal {
OffThreadIsolate::OffThreadIsolate(Isolate* isolate, Zone* zone)
: HiddenOffThreadFactory(isolate),
heap_(isolate->heap()),
isolate_(isolate),
logger_(new OffThreadLogger()),
handle_zone_(zone) {}
OffThreadIsolate::~OffThreadIsolate() { delete logger_; }
void OffThreadIsolate::FinishOffThread() {
heap()->FinishOffThread();
handle_zone_ = nullptr;
}
void OffThreadIsolate::Publish(Isolate* isolate) {
heap()->Publish(isolate->heap());
}
int OffThreadIsolate::GetNextScriptId() { return isolate_->GetNextScriptId(); }
#if V8_SFI_HAS_UNIQUE_ID
......
......@@ -9,6 +9,7 @@
#include "src/execution/thread-id.h"
#include "src/handles/handles.h"
#include "src/heap/off-thread-factory.h"
#include "src/heap/off-thread-heap.h"
namespace v8 {
namespace internal {
......@@ -37,6 +38,8 @@ class V8_EXPORT_PRIVATE OffThreadIsolate final
explicit OffThreadIsolate(Isolate* isolate, Zone* zone);
~OffThreadIsolate();
OffThreadHeap* heap() { return &heap_; }
v8::internal::OffThreadFactory* factory() {
// Upcast to the privately inherited base-class using c-style casts to avoid
// undefined behavior (as static_cast cannot cast across private bases).
......@@ -47,10 +50,13 @@ class V8_EXPORT_PRIVATE OffThreadIsolate final
// This method finishes the use of the off-thread Isolate, and can be safely
// called off-thread.
void FinishOffThread() {
factory()->FinishOffThread();
handle_zone_ = nullptr;
}
void FinishOffThread();
// This method publishes the off-thread Isolate to the main-thread Isolate,
// moving all off-thread allocated objects to be visible to the GC, and fixing
// up any other state (e.g. internalized strings). This method must be called
// on the main thread.
void Publish(Isolate* isolate);
template <typename T>
Handle<T> Throw(Handle<Object> exception) {
......@@ -84,6 +90,8 @@ class V8_EXPORT_PRIVATE OffThreadIsolate final
private:
friend class v8::internal::OffThreadFactory;
OffThreadHeap heap_;
// TODO(leszeks): Extract out the fields of the Isolate we want and store
// those instead of the whole thing.
Isolate* isolate_;
......
......@@ -2225,6 +2225,7 @@ class Heap {
friend class ScavengeTaskObserver;
friend class IncrementalMarking;
friend class IncrementalMarkingJob;
friend class OffThreadHeap;
friend class OldLargeObjectSpace;
template <typename ConcreteVisitor, typename MarkingState>
friend class MarkingVisitorBase;
......
......@@ -4,200 +4,19 @@
#include "src/heap/off-thread-factory.h"
#include "src/ast/ast-value-factory.h"
#include "src/ast/ast.h"
#include "src/base/logging.h"
#include "src/common/globals.h"
#include "src/execution/isolate.h"
#include "src/handles/handles.h"
#include "src/heap/spaces-inl.h"
#include "src/heap/spaces.h"
#include "src/numbers/hash-seed-inl.h"
#include "src/objects/fixed-array.h"
#include "src/objects/heap-object.h"
#include "src/objects/map-inl.h"
#include "src/objects/objects-body-descriptors-inl.h"
#include "src/objects/shared-function-info.h"
#include "src/objects/string.h"
#include "src/objects/visitors.h"
#include "src/roots/roots-inl.h"
#include "src/roots/roots.h"
#include "src/tracing/trace-event.h"
// Has to be the last include (doesn't have include guards)
#include "src/objects/object-macros.h"
#include "src/strings/string-hasher.h"
namespace v8 {
namespace internal {
OffThreadFactory::OffThreadFactory(Isolate* isolate)
: roots_(isolate), space_(isolate->heap()), lo_space_(isolate->heap()) {}
namespace {
class StringSlotCollectingVisitor : public ObjectVisitor {
public:
explicit StringSlotCollectingVisitor(ReadOnlyRoots roots) : roots_(roots) {}
void VisitPointers(HeapObject host, ObjectSlot start,
ObjectSlot end) override {
for (ObjectSlot slot = start; slot != end; ++slot) {
Object obj = *slot;
if (obj.IsInternalizedString() &&
!ReadOnlyHeap::Contains(HeapObject::cast(obj))) {
string_slots.emplace_back(host.address(),
slot.address() - host.address());
}
}
}
void VisitPointers(HeapObject host, MaybeObjectSlot start,
MaybeObjectSlot end) override {
for (MaybeObjectSlot slot = start; slot != end; ++slot) {
MaybeObject maybe_obj = *slot;
HeapObject obj;
if (maybe_obj.GetHeapObjectIfStrong(&obj)) {
if (obj.IsInternalizedString() && !ReadOnlyHeap::Contains(obj)) {
string_slots.emplace_back(host.address(),
slot.address() - host.address());
}
}
}
}
void VisitCodeTarget(Code host, RelocInfo* rinfo) override { UNREACHABLE(); }
void VisitEmbeddedPointer(Code host, RelocInfo* rinfo) override {
UNREACHABLE();
}
std::vector<RelativeSlot> string_slots;
private:
ReadOnlyRoots roots_;
};
} // namespace
void OffThreadFactory::FinishOffThread() {
DCHECK(!is_finished);
StringSlotCollectingVisitor string_slot_collector(read_only_roots());
// First iterate all objects in the spaces to find string slots. At this point
// all string slots have to point to off-thread strings or read-only strings.
{
PagedSpaceObjectIterator it(&space_);
for (HeapObject obj = it.Next(); !obj.is_null(); obj = it.Next()) {
obj.IterateBodyFast(&string_slot_collector);
}
}
{
LargeObjectSpaceObjectIterator it(&lo_space_);
for (HeapObject obj = it.Next(); !obj.is_null(); obj = it.Next()) {
obj.IterateBodyFast(&string_slot_collector);
}
}
string_slots_ = std::move(string_slot_collector.string_slots);
is_finished = true;
}
void OffThreadFactory::Publish(Isolate* isolate) {
DCHECK(is_finished);
HandleScope handle_scope(isolate);
// First, handlify all the string slot holder objects, so that we can keep
// track of them if they move.
//
// TODO(leszeks): We might be able to create a HandleScope-compatible
// structure off-thread and merge it into the current handle scope all in one
// go (DeferredHandles maybe?).
std::vector<Handle<HeapObject>> heap_object_handles;
std::vector<Handle<Script>> script_handles;
{
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
"V8.OffThreadFinalization.Publish.CollectHandles");
heap_object_handles.reserve(string_slots_.size());
for (RelativeSlot relative_slot : string_slots_) {
// TODO(leszeks): Group slots in the same parent object to avoid creating
// multiple duplicate handles.
HeapObject obj = HeapObject::FromAddress(relative_slot.object_address);
heap_object_handles.push_back(handle(obj, isolate));
// De-internalize the string so that we can re-internalize it later.
String string =
String::cast(RELAXED_READ_FIELD(obj, relative_slot.slot_offset));
bool one_byte = string.IsOneByteRepresentation();
Map map = one_byte ? read_only_roots().one_byte_string_map()
: read_only_roots().string_map();
string.set_map_no_write_barrier(map);
}
script_handles.reserve(script_list_.size());
for (Script script : script_list_) {
script_handles.push_back(handle(script, isolate));
}
}
// Then merge the spaces. At this point, we are allowed to point between (no
// longer) off-thread pages and main-thread heap pages, and objects in the
// previously off-thread page can move.
{
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
"V8.OffThreadFinalization.Publish.Merge");
isolate->heap()->old_space()->MergeLocalSpace(&space_);
isolate->heap()->lo_space()->MergeOffThreadSpace(&lo_space_);
}
// Iterate the string slots, as an offset from the holders we have handles to.
{
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
"V8.OffThreadFinalization.Publish.UpdateHandles");
for (size_t i = 0; i < string_slots_.size(); ++i) {
HeapObject obj = *heap_object_handles[i];
int slot_offset = string_slots_[i].slot_offset;
// There's currently no cases where the holder object could have been
// resized.
DCHECK_LT(slot_offset, obj.Size());
String string = String::cast(RELAXED_READ_FIELD(obj, slot_offset));
if (string.IsThinString()) {
// We may have already internalized this string via another slot.
String value = ThinString::cast(string).GetUnderlying();
RELAXED_WRITE_FIELD(obj, slot_offset, value);
WRITE_BARRIER(obj, slot_offset, value);
} else {
HandleScope handle_scope(isolate);
Handle<String> string_handle = handle(string, isolate);
Handle<String> internalized_string =
isolate->factory()->InternalizeString(string_handle);
DCHECK(string_handle->IsThinString() ||
string_handle->IsInternalizedString());
if (*string_handle != *internalized_string) {
// Re-read the object from the handle in case there was GC during
// internalization and it moved.
HeapObject obj = *heap_object_handles[i];
String value = *internalized_string;
RELAXED_WRITE_FIELD(obj, slot_offset, value);
WRITE_BARRIER(obj, slot_offset, value);
}
}
}
// Merge the recorded scripts into the isolate's script list.
// This for loop may seem expensive, but practically there's unlikely to be
// more than one script in the OffThreadFactory.
Handle<WeakArrayList> scripts = isolate->factory()->script_list();
for (Handle<Script> script_handle : script_handles) {
scripts = WeakArrayList::Append(isolate, scripts,
MaybeObjectHandle::Weak(script_handle));
}
isolate->heap()->SetRootScriptList(*scripts);
}
}
OffThreadFactory::OffThreadFactory(Isolate* isolate) : roots_(isolate) {}
// Hacky method for creating a simple object with a slot pointing to a string.
// TODO(leszeks): Remove once we have full FixedArray support.
......@@ -245,25 +64,13 @@ Handle<String> OffThreadFactory::InternalizeString(
}
void OffThreadFactory::AddToScriptList(Handle<Script> shared) {
script_list_.push_back(*shared);
isolate()->heap()->AddToScriptList(shared);
}
HeapObject OffThreadFactory::AllocateRaw(int size, AllocationType allocation,
AllocationAlignment alignment) {
DCHECK(!is_finished);
DCHECK_EQ(allocation, AllocationType::kOld);
AllocationResult result;
if (size > kMaxRegularHeapObjectSize) {
result = lo_space_.AllocateRaw(size);
} else {
result = space_.AllocateRaw(size, alignment);
}
return result.ToObjectChecked();
return isolate()->heap()->AllocateRaw(size, allocation, alignment);
}
} // namespace internal
} // namespace v8
// Undefine the heap manipulation macros.
#include "src/objects/object-macros-undef.h"
......@@ -28,15 +28,6 @@ class AstRawString;
class AstConsString;
class OffThreadIsolate;
struct RelativeSlot {
RelativeSlot() = default;
RelativeSlot(Address object_address, int slot_offset)
: object_address(object_address), slot_offset(slot_offset) {}
Address object_address;
int slot_offset;
};
class V8_EXPORT_PRIVATE OffThreadFactory
: public FactoryBase<OffThreadFactory> {
public:
......@@ -56,9 +47,6 @@ class V8_EXPORT_PRIVATE OffThreadFactory
Handle<String> InternalizeString(const Vector<const uint8_t>& string);
Handle<String> InternalizeString(const Vector<const uint16_t>& string);
void FinishOffThread();
void Publish(Isolate* isolate);
// The parser shouldn't allow the OffThreadFactory to get into a state where
// it generates errors.
Handle<Object> NewInvalidStringLengthError() { UNREACHABLE(); }
......@@ -93,11 +81,6 @@ class V8_EXPORT_PRIVATE OffThreadFactory
// ------
ReadOnlyRoots roots_;
OffThreadSpace space_;
OffThreadLargeObjectSpace lo_space_;
std::vector<RelativeSlot> string_slots_;
std::vector<Script> script_list_;
bool is_finished = false;
};
} // namespace internal
......
// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/heap/off-thread-heap.h"
#include "src/heap/spaces-inl.h"
#include "src/heap/spaces.h"
#include "src/objects/objects-body-descriptors-inl.h"
#include "src/roots/roots.h"
// Has to be the last include (doesn't have include guards)
#include "src/objects/object-macros.h"
namespace v8 {
namespace internal {
OffThreadHeap::OffThreadHeap(Heap* heap) : space_(heap), lo_space_(heap) {}
class OffThreadHeap::StringSlotCollectingVisitor : public ObjectVisitor {
public:
void VisitPointers(HeapObject host, ObjectSlot start,
ObjectSlot end) override {
for (ObjectSlot slot = start; slot != end; ++slot) {
Object obj = *slot;
if (obj.IsInternalizedString() &&
!ReadOnlyHeap::Contains(HeapObject::cast(obj))) {
string_slots.emplace_back(host.address(),
slot.address() - host.address());
}
}
}
void VisitPointers(HeapObject host, MaybeObjectSlot start,
MaybeObjectSlot end) override {
for (MaybeObjectSlot slot = start; slot != end; ++slot) {
MaybeObject maybe_obj = *slot;
HeapObject obj;
if (maybe_obj.GetHeapObjectIfStrong(&obj)) {
if (obj.IsInternalizedString() && !ReadOnlyHeap::Contains(obj)) {
string_slots.emplace_back(host.address(),
slot.address() - host.address());
}
}
}
}
void VisitCodeTarget(Code host, RelocInfo* rinfo) override { UNREACHABLE(); }
void VisitEmbeddedPointer(Code host, RelocInfo* rinfo) override {
UNREACHABLE();
}
std::vector<RelativeSlot> string_slots;
};
void OffThreadHeap::FinishOffThread() {
DCHECK(!is_finished);
StringSlotCollectingVisitor string_slot_collector;
// First iterate all objects in the spaces to find string slots. At this point
// all string slots have to point to off-thread strings or read-only strings.
{
PagedSpaceObjectIterator it(&space_);
for (HeapObject obj = it.Next(); !obj.is_null(); obj = it.Next()) {
obj.IterateBodyFast(&string_slot_collector);
}
}
{
LargeObjectSpaceObjectIterator it(&lo_space_);
for (HeapObject obj = it.Next(); !obj.is_null(); obj = it.Next()) {
obj.IterateBodyFast(&string_slot_collector);
}
}
string_slots_ = std::move(string_slot_collector.string_slots);
is_finished = true;
}
void OffThreadHeap::Publish(Heap* heap) {
DCHECK(is_finished);
Isolate* isolate = heap->isolate();
ReadOnlyRoots roots(isolate);
HandleScope handle_scope(isolate);
// First, handlify all the string slot holder objects, so that we can keep
// track of them if they move.
//
// TODO(leszeks): We might be able to create a HandleScope-compatible
// structure off-thread and merge it into the current handle scope all in one
// go (DeferredHandles maybe?).
std::vector<Handle<HeapObject>> heap_object_handles;
std::vector<Handle<Script>> script_handles;
{
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
"V8.OffThreadFinalization.Publish.CollectHandles");
heap_object_handles.reserve(string_slots_.size());
for (RelativeSlot relative_slot : string_slots_) {
// TODO(leszeks): Group slots in the same parent object to avoid creating
// multiple duplicate handles.
HeapObject obj = HeapObject::FromAddress(relative_slot.object_address);
heap_object_handles.push_back(handle(obj, isolate));
// De-internalize the string so that we can re-internalize it later.
String string =
String::cast(RELAXED_READ_FIELD(obj, relative_slot.slot_offset));
bool one_byte = string.IsOneByteRepresentation();
Map map = one_byte ? roots.one_byte_string_map() : roots.string_map();
string.set_map_no_write_barrier(map);
}
script_handles.reserve(script_list_.size());
for (Script script : script_list_) {
script_handles.push_back(handle(script, isolate));
}
}
// Then merge the spaces. At this point, we are allowed to point between (no
// longer) off-thread pages and main-thread heap pages, and objects in the
// previously off-thread page can move.
{
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
"V8.OffThreadFinalization.Publish.Merge");
Heap* heap = isolate->heap();
heap->old_space()->MergeLocalSpace(&space_);
heap->lo_space()->MergeOffThreadSpace(&lo_space_);
}
// Iterate the string slots, as an offset from the holders we have handles to.
{
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
"V8.OffThreadFinalization.Publish.UpdateHandles");
for (size_t i = 0; i < string_slots_.size(); ++i) {
HeapObject obj = *heap_object_handles[i];
int slot_offset = string_slots_[i].slot_offset;
// There's currently no cases where the holder object could have been
// resized.
DCHECK_LT(slot_offset, obj.Size());
String string = String::cast(RELAXED_READ_FIELD(obj, slot_offset));
if (string.IsThinString()) {
// We may have already internalized this string via another slot.
String value = ThinString::cast(string).GetUnderlying();
RELAXED_WRITE_FIELD(obj, slot_offset, value);
WRITE_BARRIER(obj, slot_offset, value);
} else {
HandleScope handle_scope(isolate);
Handle<String> string_handle = handle(string, isolate);
Handle<String> internalized_string =
isolate->factory()->InternalizeString(string_handle);
DCHECK(string_handle->IsThinString() ||
string_handle->IsInternalizedString());
if (*string_handle != *internalized_string) {
// Re-read the object from the handle in case there was GC during
// internalization and it moved.
HeapObject obj = *heap_object_handles[i];
String value = *internalized_string;
RELAXED_WRITE_FIELD(obj, slot_offset, value);
WRITE_BARRIER(obj, slot_offset, value);
}
}
}
// Merge the recorded scripts into the isolate's script list.
// This for loop may seem expensive, but practically there's unlikely to be
// more than one script in the OffThreadFactory.
Handle<WeakArrayList> scripts = isolate->factory()->script_list();
for (Handle<Script> script_handle : script_handles) {
scripts = WeakArrayList::Append(isolate, scripts,
MaybeObjectHandle::Weak(script_handle));
}
heap->SetRootScriptList(*scripts);
}
}
void OffThreadHeap::AddToScriptList(Handle<Script> shared) {
script_list_.push_back(*shared);
}
HeapObject OffThreadHeap::AllocateRaw(int size, AllocationType allocation,
AllocationAlignment alignment) {
DCHECK(!is_finished);
DCHECK_EQ(allocation, AllocationType::kOld);
AllocationResult result;
if (size > kMaxRegularHeapObjectSize) {
result = lo_space_.AllocateRaw(size);
} else {
result = space_.AllocateRaw(size, alignment);
}
return result.ToObjectChecked();
}
} // namespace internal
} // namespace v8
// Undefine the heap manipulation macros.
#include "src/objects/object-macros-undef.h"
// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_HEAP_OFF_THREAD_HEAP_H_
#define V8_HEAP_OFF_THREAD_HEAP_H_
#include <vector>
#include "src/common/globals.h"
#include "src/heap/spaces.h"
namespace v8 {
namespace internal {
class Heap;
class V8_EXPORT_PRIVATE OffThreadHeap {
public:
explicit OffThreadHeap(Heap* heap);
HeapObject AllocateRaw(int size, AllocationType allocation,
AllocationAlignment alignment = kWordAligned);
void AddToScriptList(Handle<Script> shared);
void FinishOffThread();
void Publish(Heap* heap);
private:
class StringSlotCollectingVisitor;
struct RelativeSlot {
RelativeSlot() = default;
RelativeSlot(Address object_address, int slot_offset)
: object_address(object_address), slot_offset(slot_offset) {}
Address object_address;
int slot_offset;
};
OffThreadSpace space_;
OffThreadLargeObjectSpace lo_space_;
std::vector<RelativeSlot> string_slots_;
std::vector<Script> script_list_;
bool is_finished = false;
};
} // namespace internal
} // namespace v8
#endif // V8_HEAP_OFF_THREAD_HEAP_H_
......@@ -137,11 +137,11 @@ TEST_F(OffThreadFactoryTest, OneByteInternalizedString_IsAddedToStringTable) {
off_thread_wrapper =
*off_thread_factory()->StringWrapperForTest(off_thread_string);
off_thread_factory()->FinishOffThread();
off_thread_isolate()->FinishOffThread();
}
Handle<FixedArray> wrapper = handle(off_thread_wrapper, isolate());
off_thread_factory()->Publish(isolate());
off_thread_isolate()->Publish(isolate());
Handle<String> string = handle(String::cast(wrapper->get(0)), isolate());
......@@ -180,12 +180,12 @@ TEST_F(OffThreadFactoryTest,
off_thread_wrapper_1 = *WrapString(off_thread_string_1);
off_thread_wrapper_2 = *WrapString(off_thread_string_2);
off_thread_factory()->FinishOffThread();
off_thread_isolate()->FinishOffThread();
}
Handle<FixedArray> wrapper_1 = handle(off_thread_wrapper_1, isolate());
Handle<FixedArray> wrapper_2 = handle(off_thread_wrapper_2, isolate());
off_thread_factory()->Publish(isolate());
off_thread_isolate()->Publish(isolate());
Handle<String> string_1 = handle(String::cast(wrapper_1->get(0)), isolate());
Handle<String> string_2 = handle(String::cast(wrapper_2->get(0)), isolate());
......@@ -208,11 +208,11 @@ TEST_F(OffThreadFactoryTest, AstRawString_IsInternalized) {
ast_value_factory.Internalize(off_thread_isolate());
off_thread_wrapper = *WrapString(raw_string->string());
off_thread_factory()->FinishOffThread();
off_thread_isolate()->FinishOffThread();
}
Handle<FixedArray> wrapper = handle(off_thread_wrapper, isolate());
off_thread_factory()->Publish(isolate());
off_thread_isolate()->Publish(isolate());
Handle<String> string = handle(String::cast(wrapper->get(0)), isolate());
......@@ -238,11 +238,11 @@ TEST_F(OffThreadFactoryTest, AstConsString_CreatesConsString) {
off_thread_wrapper =
*WrapString(foobar_string->GetString(off_thread_isolate()));
off_thread_factory()->FinishOffThread();
off_thread_isolate()->FinishOffThread();
}
Handle<FixedArray> wrapper = handle(off_thread_wrapper, isolate());
off_thread_factory()->Publish(isolate());
off_thread_isolate()->Publish(isolate());
Handle<String> string = handle(String::cast(wrapper->get(0)), isolate());
......@@ -261,11 +261,11 @@ TEST_F(OffThreadFactoryTest, EmptyScript) {
shared = *off_thread_factory()->NewSharedFunctionInfoForLiteral(
program, script(), true);
off_thread_factory()->FinishOffThread();
off_thread_isolate()->FinishOffThread();
}
Handle<SharedFunctionInfo> root_sfi = handle(shared, isolate());
off_thread_factory()->Publish(isolate());
off_thread_isolate()->Publish(isolate());
EXPECT_EQ(root_sfi->function_literal_id(), 0);
}
......@@ -285,11 +285,11 @@ TEST_F(OffThreadFactoryTest, LazyFunction) {
shared = *off_thread_factory()->NewSharedFunctionInfoForLiteral(
lazy, script(), true);
off_thread_factory()->FinishOffThread();
off_thread_isolate()->FinishOffThread();
}
Handle<SharedFunctionInfo> lazy_sfi = handle(shared, isolate());
off_thread_factory()->Publish(isolate());
off_thread_isolate()->Publish(isolate());
EXPECT_EQ(lazy_sfi->function_literal_id(), 1);
EXPECT_TRUE(lazy_sfi->Name().IsOneByteEqualTo(CStrVector("lazy")));
......@@ -312,11 +312,11 @@ TEST_F(OffThreadFactoryTest, EagerFunction) {
shared = *off_thread_factory()->NewSharedFunctionInfoForLiteral(
eager, script(), true);
off_thread_factory()->FinishOffThread();
off_thread_isolate()->FinishOffThread();
}
Handle<SharedFunctionInfo> eager_sfi = handle(shared, isolate());
off_thread_factory()->Publish(isolate());
off_thread_isolate()->Publish(isolate());
EXPECT_EQ(eager_sfi->function_literal_id(), 1);
EXPECT_TRUE(eager_sfi->Name().IsOneByteEqualTo(CStrVector("eager")));
......@@ -346,11 +346,11 @@ TEST_F(OffThreadFactoryTest, ImplicitNameFunction) {
shared = *off_thread_factory()->NewSharedFunctionInfoForLiteral(
implicit_name, script(), true);
off_thread_factory()->FinishOffThread();
off_thread_isolate()->FinishOffThread();
}
Handle<SharedFunctionInfo> implicit_name_sfi = handle(shared, isolate());
off_thread_factory()->Publish(isolate());
off_thread_isolate()->Publish(isolate());
EXPECT_EQ(implicit_name_sfi->function_literal_id(), 1);
EXPECT_TRUE(
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment