[offthread] Add OffThreadFactory
Introduce OffThreadFactory with initial string construction support.
The OffThreadFactory shares with Factory a new CRTP base class, called
FactoryBase. Methods in FactoryBase return a FactoryHandle<Factory, T>
alias, which is Handle<T> for normal Factory and a new OffThreadHandle<T>
for OffThreadFactory. OffThreadHandle<T> behaves like Handle<T>, except
it stores the object in-line rather than needing external storage.
Any shared factory methods are moved into FactoryBase, which uses CRTP
to call the sub-class's AllocateRaw method (plus a few more customization
points which need Isolate access on the main thread).
Methods that used to take an Isolate or Factory, and are needed off the
main thread, are now expected to be templated on the factory type and
to use the appropriate handle.
Once an OffThreadFactory has finished being used (e.g. off-thread
compilation completed) its pages are "Published" into the main-thread
Heap. To deal with string internalization without creating a bunch of
ThinStrings, this is done in two stages:
1. 'FinishOffThread': The off-thread pages are walked to
collect all slots pointing to "internalized" strings. After this is
called it is invalid to allocate any more objects with the factory.
2. 'Publish': On the main thread, we transform these slots into
<Handle to holder, offset> pairs, then for each saved slot
re-internalize its string and update the slot to point to the
internalized string.
Bug: chromium:1011762
Change-Id: I008a694da3c357de34362bd86fe7e1f46b535d5e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1992434
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/heads/master@{#65787}
2020-01-15 11:47:41 +00:00
|
|
|
// 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 <cmath>
|
|
|
|
#include <iostream>
|
|
|
|
#include <limits>
|
|
|
|
#include <memory>
|
|
|
|
|
2020-01-15 11:59:56 +00:00
|
|
|
#include "src/ast/ast-value-factory.h"
|
2020-02-13 09:39:04 +00:00
|
|
|
#include "src/ast/ast.h"
|
|
|
|
#include "src/ast/scopes.h"
|
|
|
|
#include "src/common/assert-scope.h"
|
|
|
|
#include "src/common/globals.h"
|
[offthread] Add OffThreadFactory
Introduce OffThreadFactory with initial string construction support.
The OffThreadFactory shares with Factory a new CRTP base class, called
FactoryBase. Methods in FactoryBase return a FactoryHandle<Factory, T>
alias, which is Handle<T> for normal Factory and a new OffThreadHandle<T>
for OffThreadFactory. OffThreadHandle<T> behaves like Handle<T>, except
it stores the object in-line rather than needing external storage.
Any shared factory methods are moved into FactoryBase, which uses CRTP
to call the sub-class's AllocateRaw method (plus a few more customization
points which need Isolate access on the main thread).
Methods that used to take an Isolate or Factory, and are needed off the
main thread, are now expected to be templated on the factory type and
to use the appropriate handle.
Once an OffThreadFactory has finished being used (e.g. off-thread
compilation completed) its pages are "Published" into the main-thread
Heap. To deal with string internalization without creating a bunch of
ThinStrings, this is done in two stages:
1. 'FinishOffThread': The off-thread pages are walked to
collect all slots pointing to "internalized" strings. After this is
called it is invalid to allocate any more objects with the factory.
2. 'Publish': On the main thread, we transform these slots into
<Handle to holder, offset> pairs, then for each saved slot
re-internalize its string and update the slot to point to the
internalized string.
Bug: chromium:1011762
Change-Id: I008a694da3c357de34362bd86fe7e1f46b535d5e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1992434
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/heads/master@{#65787}
2020-01-15 11:47:41 +00:00
|
|
|
#include "src/handles/handles-inl.h"
|
2020-01-15 11:59:56 +00:00
|
|
|
#include "src/handles/handles.h"
|
2020-04-22 10:45:31 +00:00
|
|
|
#include "src/handles/maybe-handles.h"
|
2020-08-13 12:12:17 +00:00
|
|
|
#include "src/heap/local-factory-inl.h"
|
2020-01-15 11:59:56 +00:00
|
|
|
#include "src/objects/fixed-array.h"
|
2020-02-13 09:39:04 +00:00
|
|
|
#include "src/objects/script.h"
|
|
|
|
#include "src/objects/shared-function-info.h"
|
[offthread] Add OffThreadFactory
Introduce OffThreadFactory with initial string construction support.
The OffThreadFactory shares with Factory a new CRTP base class, called
FactoryBase. Methods in FactoryBase return a FactoryHandle<Factory, T>
alias, which is Handle<T> for normal Factory and a new OffThreadHandle<T>
for OffThreadFactory. OffThreadHandle<T> behaves like Handle<T>, except
it stores the object in-line rather than needing external storage.
Any shared factory methods are moved into FactoryBase, which uses CRTP
to call the sub-class's AllocateRaw method (plus a few more customization
points which need Isolate access on the main thread).
Methods that used to take an Isolate or Factory, and are needed off the
main thread, are now expected to be templated on the factory type and
to use the appropriate handle.
Once an OffThreadFactory has finished being used (e.g. off-thread
compilation completed) its pages are "Published" into the main-thread
Heap. To deal with string internalization without creating a bunch of
ThinStrings, this is done in two stages:
1. 'FinishOffThread': The off-thread pages are walked to
collect all slots pointing to "internalized" strings. After this is
called it is invalid to allocate any more objects with the factory.
2. 'Publish': On the main thread, we transform these slots into
<Handle to holder, offset> pairs, then for each saved slot
re-internalize its string and update the slot to point to the
internalized string.
Bug: chromium:1011762
Change-Id: I008a694da3c357de34362bd86fe7e1f46b535d5e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1992434
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/heads/master@{#65787}
2020-01-15 11:47:41 +00:00
|
|
|
#include "src/objects/string.h"
|
2020-02-13 09:39:04 +00:00
|
|
|
#include "src/parsing/parse-info.h"
|
|
|
|
#include "src/parsing/parser.h"
|
|
|
|
#include "src/parsing/rewriter.h"
|
|
|
|
#include "src/parsing/scanner-character-streams.h"
|
|
|
|
#include "src/parsing/scanner.h"
|
|
|
|
#include "src/strings/unicode-inl.h"
|
|
|
|
#include "src/utils/utils.h"
|
[offthread] Add OffThreadFactory
Introduce OffThreadFactory with initial string construction support.
The OffThreadFactory shares with Factory a new CRTP base class, called
FactoryBase. Methods in FactoryBase return a FactoryHandle<Factory, T>
alias, which is Handle<T> for normal Factory and a new OffThreadHandle<T>
for OffThreadFactory. OffThreadHandle<T> behaves like Handle<T>, except
it stores the object in-line rather than needing external storage.
Any shared factory methods are moved into FactoryBase, which uses CRTP
to call the sub-class's AllocateRaw method (plus a few more customization
points which need Isolate access on the main thread).
Methods that used to take an Isolate or Factory, and are needed off the
main thread, are now expected to be templated on the factory type and
to use the appropriate handle.
Once an OffThreadFactory has finished being used (e.g. off-thread
compilation completed) its pages are "Published" into the main-thread
Heap. To deal with string internalization without creating a bunch of
ThinStrings, this is done in two stages:
1. 'FinishOffThread': The off-thread pages are walked to
collect all slots pointing to "internalized" strings. After this is
called it is invalid to allocate any more objects with the factory.
2. 'Publish': On the main thread, we transform these slots into
<Handle to holder, offset> pairs, then for each saved slot
re-internalize its string and update the slot to point to the
internalized string.
Bug: chromium:1011762
Change-Id: I008a694da3c357de34362bd86fe7e1f46b535d5e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1992434
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/heads/master@{#65787}
2020-01-15 11:47:41 +00:00
|
|
|
#include "test/unittests/test-utils.h"
|
|
|
|
|
|
|
|
namespace v8 {
|
|
|
|
namespace internal {
|
|
|
|
|
2020-08-13 12:12:17 +00:00
|
|
|
class LocalIsolate;
|
[offthread] Add an OffThreadIsolate
The Factory/OffThreadFactory allows us to cleanly separate object
construction behaviour between main-thread and off-thread in a
syntactically consistent way (so that methods templated on the factory
type can be made to work on both).
However, there are cases where we also have to access the Isolate, for
handle creation or exception throwing. So far we have been pushing more
and more "customization points" into the factories to allow these
factory-templated methods to dispatch on this isolate behaviour via
these factory methods. Unfortunately, this is an increasing layering
violation between Factory and Isolate, particularly around exception
handling.
Now, we introduce an OffThreadIsolate, analogous to Isolate in the same
way as OffThreadFactory is analogous to Factory. All methods which were
templated on Factory are now templated on Isolate, and methods which
used to take an Isolate, and which were recently changed to take a
templated Factory, are changed/reverted to take a templated Isolate.
OffThreadFactory gets an isolate() method to match Factory's.
Notably, FactoryHandle is changed to "HandleFor", where the template
argument can be either of the Isolate type or the Factory type (allowing
us to dispatch on both depending on what is available).
Bug: chromium:1011762
Change-Id: Id144176f7da534dd76f3d535ab2ade008b6845e3
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2030909
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#66101}
2020-02-04 10:50:53 +00:00
|
|
|
|
2020-02-13 09:39:04 +00:00
|
|
|
namespace {
|
|
|
|
|
|
|
|
std::vector<uint16_t> DecodeUtf8(const std::string& string) {
|
|
|
|
if (string.empty()) return {};
|
|
|
|
|
2021-06-17 15:43:55 +00:00
|
|
|
auto utf8_data = base::Vector<const uint8_t>::cast(
|
|
|
|
base::VectorOf(string.data(), string.length()));
|
2020-02-13 09:39:04 +00:00
|
|
|
Utf8Decoder decoder(utf8_data);
|
|
|
|
|
|
|
|
std::vector<uint16_t> utf16(decoder.utf16_length());
|
|
|
|
decoder.Decode(&utf16[0], utf8_data);
|
|
|
|
|
|
|
|
return utf16;
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace
|
|
|
|
|
2020-08-13 12:12:17 +00:00
|
|
|
class LocalFactoryTest : public TestWithIsolateAndZone {
|
[offthread] Add OffThreadFactory
Introduce OffThreadFactory with initial string construction support.
The OffThreadFactory shares with Factory a new CRTP base class, called
FactoryBase. Methods in FactoryBase return a FactoryHandle<Factory, T>
alias, which is Handle<T> for normal Factory and a new OffThreadHandle<T>
for OffThreadFactory. OffThreadHandle<T> behaves like Handle<T>, except
it stores the object in-line rather than needing external storage.
Any shared factory methods are moved into FactoryBase, which uses CRTP
to call the sub-class's AllocateRaw method (plus a few more customization
points which need Isolate access on the main thread).
Methods that used to take an Isolate or Factory, and are needed off the
main thread, are now expected to be templated on the factory type and
to use the appropriate handle.
Once an OffThreadFactory has finished being used (e.g. off-thread
compilation completed) its pages are "Published" into the main-thread
Heap. To deal with string internalization without creating a bunch of
ThinStrings, this is done in two stages:
1. 'FinishOffThread': The off-thread pages are walked to
collect all slots pointing to "internalized" strings. After this is
called it is invalid to allocate any more objects with the factory.
2. 'Publish': On the main thread, we transform these slots into
<Handle to holder, offset> pairs, then for each saved slot
re-internalize its string and update the slot to point to the
internalized string.
Bug: chromium:1011762
Change-Id: I008a694da3c357de34362bd86fe7e1f46b535d5e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1992434
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/heads/master@{#65787}
2020-01-15 11:47:41 +00:00
|
|
|
public:
|
2020-08-13 12:12:17 +00:00
|
|
|
LocalFactoryTest()
|
2020-02-13 09:39:04 +00:00
|
|
|
: TestWithIsolateAndZone(),
|
2020-04-22 10:47:32 +00:00
|
|
|
state_(isolate()),
|
|
|
|
parse_info_(
|
|
|
|
isolate(),
|
|
|
|
UnoptimizedCompileFlags::ForToplevelCompile(
|
|
|
|
isolate(), true, construct_language_mode(FLAG_use_strict),
|
2021-07-01 12:11:36 +00:00
|
|
|
REPLMode::kNo, ScriptType::kClassic, FLAG_lazy),
|
2020-04-22 10:47:32 +00:00
|
|
|
&state_),
|
2021-07-01 12:11:36 +00:00
|
|
|
local_isolate_(isolate()->main_thread_local_isolate()) {}
|
2020-02-13 09:39:04 +00:00
|
|
|
|
|
|
|
FunctionLiteral* ParseProgram(const char* source) {
|
|
|
|
auto utf16_source = DecodeUtf8(source);
|
|
|
|
|
|
|
|
// Normally this would be an external string or whatever, we don't have to
|
|
|
|
// worry about it for now.
|
2021-06-17 15:43:55 +00:00
|
|
|
source_string_ = factory()
|
|
|
|
->NewStringFromUtf8(base::CStrVector(source))
|
|
|
|
.ToHandleChecked();
|
2020-02-13 09:39:04 +00:00
|
|
|
|
|
|
|
parse_info_.set_character_stream(
|
|
|
|
ScannerStream::ForTesting(utf16_source.data(), utf16_source.size()));
|
|
|
|
|
|
|
|
{
|
2020-11-20 16:57:36 +00:00
|
|
|
DisallowGarbageCollection no_gc;
|
2020-02-13 09:39:04 +00:00
|
|
|
DisallowHeapAccess no_heap_access;
|
|
|
|
|
|
|
|
Parser parser(parse_info());
|
|
|
|
parser.InitializeEmptyScopeChain(parse_info());
|
2020-04-22 10:45:31 +00:00
|
|
|
parser.ParseOnBackground(parse_info(), 0, 0, kFunctionLiteralIdTopLevel);
|
2020-02-13 09:39:04 +00:00
|
|
|
}
|
|
|
|
|
2020-08-13 12:12:17 +00:00
|
|
|
parse_info()->ast_value_factory()->Internalize(local_isolate());
|
|
|
|
DeclarationScope::AllocateScopeInfos(parse_info(), local_isolate());
|
2020-02-13 09:39:04 +00:00
|
|
|
|
2020-08-13 12:12:17 +00:00
|
|
|
script_ = parse_info_.CreateScript(local_isolate(),
|
|
|
|
local_factory()->empty_string(),
|
2020-04-22 10:45:31 +00:00
|
|
|
kNullMaybeHandle, ScriptOriginOptions());
|
2020-02-13 09:39:04 +00:00
|
|
|
|
|
|
|
// Create the SFI list on the script so that SFI SetScript works.
|
2020-08-13 12:12:17 +00:00
|
|
|
Handle<WeakFixedArray> infos = local_factory()->NewWeakFixedArray(
|
2020-02-28 12:24:46 +00:00
|
|
|
parse_info()->max_function_literal_id() + 1, AllocationType::kOld);
|
2020-02-13 09:39:04 +00:00
|
|
|
script_->set_shared_function_infos(*infos);
|
|
|
|
|
|
|
|
return parse_info()->literal();
|
|
|
|
}
|
|
|
|
|
|
|
|
ParseInfo* parse_info() { return &parse_info_; }
|
|
|
|
|
2020-02-28 12:24:46 +00:00
|
|
|
Handle<Script> script() { return script_; }
|
[offthread] Add OffThreadFactory
Introduce OffThreadFactory with initial string construction support.
The OffThreadFactory shares with Factory a new CRTP base class, called
FactoryBase. Methods in FactoryBase return a FactoryHandle<Factory, T>
alias, which is Handle<T> for normal Factory and a new OffThreadHandle<T>
for OffThreadFactory. OffThreadHandle<T> behaves like Handle<T>, except
it stores the object in-line rather than needing external storage.
Any shared factory methods are moved into FactoryBase, which uses CRTP
to call the sub-class's AllocateRaw method (plus a few more customization
points which need Isolate access on the main thread).
Methods that used to take an Isolate or Factory, and are needed off the
main thread, are now expected to be templated on the factory type and
to use the appropriate handle.
Once an OffThreadFactory has finished being used (e.g. off-thread
compilation completed) its pages are "Published" into the main-thread
Heap. To deal with string internalization without creating a bunch of
ThinStrings, this is done in two stages:
1. 'FinishOffThread': The off-thread pages are walked to
collect all slots pointing to "internalized" strings. After this is
called it is invalid to allocate any more objects with the factory.
2. 'Publish': On the main thread, we transform these slots into
<Handle to holder, offset> pairs, then for each saved slot
re-internalize its string and update the slot to point to the
internalized string.
Bug: chromium:1011762
Change-Id: I008a694da3c357de34362bd86fe7e1f46b535d5e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1992434
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/heads/master@{#65787}
2020-01-15 11:47:41 +00:00
|
|
|
|
2020-11-17 10:16:09 +00:00
|
|
|
LocalIsolate* local_isolate() { return local_isolate_; }
|
2020-08-13 12:12:17 +00:00
|
|
|
LocalFactory* local_factory() { return local_isolate()->factory(); }
|
2020-01-15 11:59:56 +00:00
|
|
|
|
[offthread] Add OffThreadFactory
Introduce OffThreadFactory with initial string construction support.
The OffThreadFactory shares with Factory a new CRTP base class, called
FactoryBase. Methods in FactoryBase return a FactoryHandle<Factory, T>
alias, which is Handle<T> for normal Factory and a new OffThreadHandle<T>
for OffThreadFactory. OffThreadHandle<T> behaves like Handle<T>, except
it stores the object in-line rather than needing external storage.
Any shared factory methods are moved into FactoryBase, which uses CRTP
to call the sub-class's AllocateRaw method (plus a few more customization
points which need Isolate access on the main thread).
Methods that used to take an Isolate or Factory, and are needed off the
main thread, are now expected to be templated on the factory type and
to use the appropriate handle.
Once an OffThreadFactory has finished being used (e.g. off-thread
compilation completed) its pages are "Published" into the main-thread
Heap. To deal with string internalization without creating a bunch of
ThinStrings, this is done in two stages:
1. 'FinishOffThread': The off-thread pages are walked to
collect all slots pointing to "internalized" strings. After this is
called it is invalid to allocate any more objects with the factory.
2. 'Publish': On the main thread, we transform these slots into
<Handle to holder, offset> pairs, then for each saved slot
re-internalize its string and update the slot to point to the
internalized string.
Bug: chromium:1011762
Change-Id: I008a694da3c357de34362bd86fe7e1f46b535d5e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1992434
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/heads/master@{#65787}
2020-01-15 11:47:41 +00:00
|
|
|
private:
|
2020-08-13 12:12:17 +00:00
|
|
|
SaveFlags save_flags_;
|
2020-04-22 10:47:32 +00:00
|
|
|
UnoptimizedCompileState state_;
|
2020-02-13 09:39:04 +00:00
|
|
|
ParseInfo parse_info_;
|
2020-11-17 10:16:09 +00:00
|
|
|
LocalIsolate* local_isolate_;
|
2020-02-13 09:39:04 +00:00
|
|
|
Handle<String> source_string_;
|
2020-02-28 12:24:46 +00:00
|
|
|
Handle<Script> script_;
|
[offthread] Add OffThreadFactory
Introduce OffThreadFactory with initial string construction support.
The OffThreadFactory shares with Factory a new CRTP base class, called
FactoryBase. Methods in FactoryBase return a FactoryHandle<Factory, T>
alias, which is Handle<T> for normal Factory and a new OffThreadHandle<T>
for OffThreadFactory. OffThreadHandle<T> behaves like Handle<T>, except
it stores the object in-line rather than needing external storage.
Any shared factory methods are moved into FactoryBase, which uses CRTP
to call the sub-class's AllocateRaw method (plus a few more customization
points which need Isolate access on the main thread).
Methods that used to take an Isolate or Factory, and are needed off the
main thread, are now expected to be templated on the factory type and
to use the appropriate handle.
Once an OffThreadFactory has finished being used (e.g. off-thread
compilation completed) its pages are "Published" into the main-thread
Heap. To deal with string internalization without creating a bunch of
ThinStrings, this is done in two stages:
1. 'FinishOffThread': The off-thread pages are walked to
collect all slots pointing to "internalized" strings. After this is
called it is invalid to allocate any more objects with the factory.
2. 'Publish': On the main thread, we transform these slots into
<Handle to holder, offset> pairs, then for each saved slot
re-internalize its string and update the slot to point to the
internalized string.
Bug: chromium:1011762
Change-Id: I008a694da3c357de34362bd86fe7e1f46b535d5e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1992434
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/heads/master@{#65787}
2020-01-15 11:47:41 +00:00
|
|
|
};
|
|
|
|
|
2020-08-13 12:12:17 +00:00
|
|
|
TEST_F(LocalFactoryTest, OneByteInternalizedString_IsAddedToStringTable) {
|
2021-06-17 15:43:55 +00:00
|
|
|
base::Vector<const uint8_t> string_vector = base::StaticOneByteVector("foo");
|
[offthread] Add OffThreadFactory
Introduce OffThreadFactory with initial string construction support.
The OffThreadFactory shares with Factory a new CRTP base class, called
FactoryBase. Methods in FactoryBase return a FactoryHandle<Factory, T>
alias, which is Handle<T> for normal Factory and a new OffThreadHandle<T>
for OffThreadFactory. OffThreadHandle<T> behaves like Handle<T>, except
it stores the object in-line rather than needing external storage.
Any shared factory methods are moved into FactoryBase, which uses CRTP
to call the sub-class's AllocateRaw method (plus a few more customization
points which need Isolate access on the main thread).
Methods that used to take an Isolate or Factory, and are needed off the
main thread, are now expected to be templated on the factory type and
to use the appropriate handle.
Once an OffThreadFactory has finished being used (e.g. off-thread
compilation completed) its pages are "Published" into the main-thread
Heap. To deal with string internalization without creating a bunch of
ThinStrings, this is done in two stages:
1. 'FinishOffThread': The off-thread pages are walked to
collect all slots pointing to "internalized" strings. After this is
called it is invalid to allocate any more objects with the factory.
2. 'Publish': On the main thread, we transform these slots into
<Handle to holder, offset> pairs, then for each saved slot
re-internalize its string and update the slot to point to the
internalized string.
Bug: chromium:1011762
Change-Id: I008a694da3c357de34362bd86fe7e1f46b535d5e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1992434
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/heads/master@{#65787}
2020-01-15 11:47:41 +00:00
|
|
|
|
2020-08-13 12:12:17 +00:00
|
|
|
Handle<String> string;
|
2020-02-28 12:24:46 +00:00
|
|
|
{
|
2020-08-13 12:12:17 +00:00
|
|
|
LocalHandleScope handle_scope(local_isolate());
|
[offthread] Add OffThreadFactory
Introduce OffThreadFactory with initial string construction support.
The OffThreadFactory shares with Factory a new CRTP base class, called
FactoryBase. Methods in FactoryBase return a FactoryHandle<Factory, T>
alias, which is Handle<T> for normal Factory and a new OffThreadHandle<T>
for OffThreadFactory. OffThreadHandle<T> behaves like Handle<T>, except
it stores the object in-line rather than needing external storage.
Any shared factory methods are moved into FactoryBase, which uses CRTP
to call the sub-class's AllocateRaw method (plus a few more customization
points which need Isolate access on the main thread).
Methods that used to take an Isolate or Factory, and are needed off the
main thread, are now expected to be templated on the factory type and
to use the appropriate handle.
Once an OffThreadFactory has finished being used (e.g. off-thread
compilation completed) its pages are "Published" into the main-thread
Heap. To deal with string internalization without creating a bunch of
ThinStrings, this is done in two stages:
1. 'FinishOffThread': The off-thread pages are walked to
collect all slots pointing to "internalized" strings. After this is
called it is invalid to allocate any more objects with the factory.
2. 'Publish': On the main thread, we transform these slots into
<Handle to holder, offset> pairs, then for each saved slot
re-internalize its string and update the slot to point to the
internalized string.
Bug: chromium:1011762
Change-Id: I008a694da3c357de34362bd86fe7e1f46b535d5e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1992434
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/heads/master@{#65787}
2020-01-15 11:47:41 +00:00
|
|
|
|
2020-08-13 12:12:17 +00:00
|
|
|
Handle<String> local_string =
|
|
|
|
local_factory()->InternalizeString(string_vector);
|
[offthread] Add OffThreadFactory
Introduce OffThreadFactory with initial string construction support.
The OffThreadFactory shares with Factory a new CRTP base class, called
FactoryBase. Methods in FactoryBase return a FactoryHandle<Factory, T>
alias, which is Handle<T> for normal Factory and a new OffThreadHandle<T>
for OffThreadFactory. OffThreadHandle<T> behaves like Handle<T>, except
it stores the object in-line rather than needing external storage.
Any shared factory methods are moved into FactoryBase, which uses CRTP
to call the sub-class's AllocateRaw method (plus a few more customization
points which need Isolate access on the main thread).
Methods that used to take an Isolate or Factory, and are needed off the
main thread, are now expected to be templated on the factory type and
to use the appropriate handle.
Once an OffThreadFactory has finished being used (e.g. off-thread
compilation completed) its pages are "Published" into the main-thread
Heap. To deal with string internalization without creating a bunch of
ThinStrings, this is done in two stages:
1. 'FinishOffThread': The off-thread pages are walked to
collect all slots pointing to "internalized" strings. After this is
called it is invalid to allocate any more objects with the factory.
2. 'Publish': On the main thread, we transform these slots into
<Handle to holder, offset> pairs, then for each saved slot
re-internalize its string and update the slot to point to the
internalized string.
Bug: chromium:1011762
Change-Id: I008a694da3c357de34362bd86fe7e1f46b535d5e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1992434
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/heads/master@{#65787}
2020-01-15 11:47:41 +00:00
|
|
|
|
2020-08-13 12:12:17 +00:00
|
|
|
string = local_isolate()->heap()->NewPersistentHandle(local_string);
|
2020-02-28 12:24:46 +00:00
|
|
|
}
|
[offthread] Add OffThreadFactory
Introduce OffThreadFactory with initial string construction support.
The OffThreadFactory shares with Factory a new CRTP base class, called
FactoryBase. Methods in FactoryBase return a FactoryHandle<Factory, T>
alias, which is Handle<T> for normal Factory and a new OffThreadHandle<T>
for OffThreadFactory. OffThreadHandle<T> behaves like Handle<T>, except
it stores the object in-line rather than needing external storage.
Any shared factory methods are moved into FactoryBase, which uses CRTP
to call the sub-class's AllocateRaw method (plus a few more customization
points which need Isolate access on the main thread).
Methods that used to take an Isolate or Factory, and are needed off the
main thread, are now expected to be templated on the factory type and
to use the appropriate handle.
Once an OffThreadFactory has finished being used (e.g. off-thread
compilation completed) its pages are "Published" into the main-thread
Heap. To deal with string internalization without creating a bunch of
ThinStrings, this is done in two stages:
1. 'FinishOffThread': The off-thread pages are walked to
collect all slots pointing to "internalized" strings. After this is
called it is invalid to allocate any more objects with the factory.
2. 'Publish': On the main thread, we transform these slots into
<Handle to holder, offset> pairs, then for each saved slot
re-internalize its string and update the slot to point to the
internalized string.
Bug: chromium:1011762
Change-Id: I008a694da3c357de34362bd86fe7e1f46b535d5e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1992434
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/heads/master@{#65787}
2020-01-15 11:47:41 +00:00
|
|
|
|
2021-06-17 15:43:55 +00:00
|
|
|
EXPECT_TRUE(string->IsOneByteEqualTo(base::CStrVector("foo")));
|
[offthread] Add OffThreadFactory
Introduce OffThreadFactory with initial string construction support.
The OffThreadFactory shares with Factory a new CRTP base class, called
FactoryBase. Methods in FactoryBase return a FactoryHandle<Factory, T>
alias, which is Handle<T> for normal Factory and a new OffThreadHandle<T>
for OffThreadFactory. OffThreadHandle<T> behaves like Handle<T>, except
it stores the object in-line rather than needing external storage.
Any shared factory methods are moved into FactoryBase, which uses CRTP
to call the sub-class's AllocateRaw method (plus a few more customization
points which need Isolate access on the main thread).
Methods that used to take an Isolate or Factory, and are needed off the
main thread, are now expected to be templated on the factory type and
to use the appropriate handle.
Once an OffThreadFactory has finished being used (e.g. off-thread
compilation completed) its pages are "Published" into the main-thread
Heap. To deal with string internalization without creating a bunch of
ThinStrings, this is done in two stages:
1. 'FinishOffThread': The off-thread pages are walked to
collect all slots pointing to "internalized" strings. After this is
called it is invalid to allocate any more objects with the factory.
2. 'Publish': On the main thread, we transform these slots into
<Handle to holder, offset> pairs, then for each saved slot
re-internalize its string and update the slot to point to the
internalized string.
Bug: chromium:1011762
Change-Id: I008a694da3c357de34362bd86fe7e1f46b535d5e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1992434
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/heads/master@{#65787}
2020-01-15 11:47:41 +00:00
|
|
|
EXPECT_TRUE(string->IsInternalizedString());
|
|
|
|
|
|
|
|
Handle<String> same_string = isolate()
|
|
|
|
->factory()
|
|
|
|
->NewStringFromOneByte(string_vector)
|
|
|
|
.ToHandleChecked();
|
|
|
|
EXPECT_NE(*string, *same_string);
|
|
|
|
EXPECT_FALSE(same_string->IsInternalizedString());
|
|
|
|
|
|
|
|
Handle<String> internalized_string =
|
|
|
|
isolate()->factory()->InternalizeString(same_string);
|
|
|
|
EXPECT_EQ(*string, *internalized_string);
|
|
|
|
}
|
|
|
|
|
2020-08-13 12:12:17 +00:00
|
|
|
TEST_F(LocalFactoryTest, OneByteInternalizedString_DuplicateIsDeduplicated) {
|
2021-06-17 15:43:55 +00:00
|
|
|
base::Vector<const uint8_t> string_vector = base::StaticOneByteVector("foo");
|
[offthread] Add OffThreadFactory
Introduce OffThreadFactory with initial string construction support.
The OffThreadFactory shares with Factory a new CRTP base class, called
FactoryBase. Methods in FactoryBase return a FactoryHandle<Factory, T>
alias, which is Handle<T> for normal Factory and a new OffThreadHandle<T>
for OffThreadFactory. OffThreadHandle<T> behaves like Handle<T>, except
it stores the object in-line rather than needing external storage.
Any shared factory methods are moved into FactoryBase, which uses CRTP
to call the sub-class's AllocateRaw method (plus a few more customization
points which need Isolate access on the main thread).
Methods that used to take an Isolate or Factory, and are needed off the
main thread, are now expected to be templated on the factory type and
to use the appropriate handle.
Once an OffThreadFactory has finished being used (e.g. off-thread
compilation completed) its pages are "Published" into the main-thread
Heap. To deal with string internalization without creating a bunch of
ThinStrings, this is done in two stages:
1. 'FinishOffThread': The off-thread pages are walked to
collect all slots pointing to "internalized" strings. After this is
called it is invalid to allocate any more objects with the factory.
2. 'Publish': On the main thread, we transform these slots into
<Handle to holder, offset> pairs, then for each saved slot
re-internalize its string and update the slot to point to the
internalized string.
Bug: chromium:1011762
Change-Id: I008a694da3c357de34362bd86fe7e1f46b535d5e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1992434
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/heads/master@{#65787}
2020-01-15 11:47:41 +00:00
|
|
|
|
2020-08-13 12:12:17 +00:00
|
|
|
Handle<String> string_1;
|
|
|
|
Handle<String> string_2;
|
2020-02-28 12:24:46 +00:00
|
|
|
{
|
2020-08-13 12:12:17 +00:00
|
|
|
LocalHandleScope handle_scope(local_isolate());
|
[offthread] Add OffThreadFactory
Introduce OffThreadFactory with initial string construction support.
The OffThreadFactory shares with Factory a new CRTP base class, called
FactoryBase. Methods in FactoryBase return a FactoryHandle<Factory, T>
alias, which is Handle<T> for normal Factory and a new OffThreadHandle<T>
for OffThreadFactory. OffThreadHandle<T> behaves like Handle<T>, except
it stores the object in-line rather than needing external storage.
Any shared factory methods are moved into FactoryBase, which uses CRTP
to call the sub-class's AllocateRaw method (plus a few more customization
points which need Isolate access on the main thread).
Methods that used to take an Isolate or Factory, and are needed off the
main thread, are now expected to be templated on the factory type and
to use the appropriate handle.
Once an OffThreadFactory has finished being used (e.g. off-thread
compilation completed) its pages are "Published" into the main-thread
Heap. To deal with string internalization without creating a bunch of
ThinStrings, this is done in two stages:
1. 'FinishOffThread': The off-thread pages are walked to
collect all slots pointing to "internalized" strings. After this is
called it is invalid to allocate any more objects with the factory.
2. 'Publish': On the main thread, we transform these slots into
<Handle to holder, offset> pairs, then for each saved slot
re-internalize its string and update the slot to point to the
internalized string.
Bug: chromium:1011762
Change-Id: I008a694da3c357de34362bd86fe7e1f46b535d5e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1992434
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/heads/master@{#65787}
2020-01-15 11:47:41 +00:00
|
|
|
|
2020-08-13 12:12:17 +00:00
|
|
|
Handle<String> local_string_1 =
|
|
|
|
local_factory()->InternalizeString(string_vector);
|
|
|
|
Handle<String> local_string_2 =
|
|
|
|
local_factory()->InternalizeString(string_vector);
|
[offthread] Add OffThreadFactory
Introduce OffThreadFactory with initial string construction support.
The OffThreadFactory shares with Factory a new CRTP base class, called
FactoryBase. Methods in FactoryBase return a FactoryHandle<Factory, T>
alias, which is Handle<T> for normal Factory and a new OffThreadHandle<T>
for OffThreadFactory. OffThreadHandle<T> behaves like Handle<T>, except
it stores the object in-line rather than needing external storage.
Any shared factory methods are moved into FactoryBase, which uses CRTP
to call the sub-class's AllocateRaw method (plus a few more customization
points which need Isolate access on the main thread).
Methods that used to take an Isolate or Factory, and are needed off the
main thread, are now expected to be templated on the factory type and
to use the appropriate handle.
Once an OffThreadFactory has finished being used (e.g. off-thread
compilation completed) its pages are "Published" into the main-thread
Heap. To deal with string internalization without creating a bunch of
ThinStrings, this is done in two stages:
1. 'FinishOffThread': The off-thread pages are walked to
collect all slots pointing to "internalized" strings. After this is
called it is invalid to allocate any more objects with the factory.
2. 'Publish': On the main thread, we transform these slots into
<Handle to holder, offset> pairs, then for each saved slot
re-internalize its string and update the slot to point to the
internalized string.
Bug: chromium:1011762
Change-Id: I008a694da3c357de34362bd86fe7e1f46b535d5e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1992434
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/heads/master@{#65787}
2020-01-15 11:47:41 +00:00
|
|
|
|
2020-08-13 12:12:17 +00:00
|
|
|
string_1 = local_isolate()->heap()->NewPersistentHandle(local_string_1);
|
|
|
|
string_2 = local_isolate()->heap()->NewPersistentHandle(local_string_2);
|
|
|
|
}
|
[offthread] Add OffThreadFactory
Introduce OffThreadFactory with initial string construction support.
The OffThreadFactory shares with Factory a new CRTP base class, called
FactoryBase. Methods in FactoryBase return a FactoryHandle<Factory, T>
alias, which is Handle<T> for normal Factory and a new OffThreadHandle<T>
for OffThreadFactory. OffThreadHandle<T> behaves like Handle<T>, except
it stores the object in-line rather than needing external storage.
Any shared factory methods are moved into FactoryBase, which uses CRTP
to call the sub-class's AllocateRaw method (plus a few more customization
points which need Isolate access on the main thread).
Methods that used to take an Isolate or Factory, and are needed off the
main thread, are now expected to be templated on the factory type and
to use the appropriate handle.
Once an OffThreadFactory has finished being used (e.g. off-thread
compilation completed) its pages are "Published" into the main-thread
Heap. To deal with string internalization without creating a bunch of
ThinStrings, this is done in two stages:
1. 'FinishOffThread': The off-thread pages are walked to
collect all slots pointing to "internalized" strings. After this is
called it is invalid to allocate any more objects with the factory.
2. 'Publish': On the main thread, we transform these slots into
<Handle to holder, offset> pairs, then for each saved slot
re-internalize its string and update the slot to point to the
internalized string.
Bug: chromium:1011762
Change-Id: I008a694da3c357de34362bd86fe7e1f46b535d5e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1992434
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/heads/master@{#65787}
2020-01-15 11:47:41 +00:00
|
|
|
|
2021-06-17 15:43:55 +00:00
|
|
|
EXPECT_TRUE(string_1->IsOneByteEqualTo(base::CStrVector("foo")));
|
[offthread] Add OffThreadFactory
Introduce OffThreadFactory with initial string construction support.
The OffThreadFactory shares with Factory a new CRTP base class, called
FactoryBase. Methods in FactoryBase return a FactoryHandle<Factory, T>
alias, which is Handle<T> for normal Factory and a new OffThreadHandle<T>
for OffThreadFactory. OffThreadHandle<T> behaves like Handle<T>, except
it stores the object in-line rather than needing external storage.
Any shared factory methods are moved into FactoryBase, which uses CRTP
to call the sub-class's AllocateRaw method (plus a few more customization
points which need Isolate access on the main thread).
Methods that used to take an Isolate or Factory, and are needed off the
main thread, are now expected to be templated on the factory type and
to use the appropriate handle.
Once an OffThreadFactory has finished being used (e.g. off-thread
compilation completed) its pages are "Published" into the main-thread
Heap. To deal with string internalization without creating a bunch of
ThinStrings, this is done in two stages:
1. 'FinishOffThread': The off-thread pages are walked to
collect all slots pointing to "internalized" strings. After this is
called it is invalid to allocate any more objects with the factory.
2. 'Publish': On the main thread, we transform these slots into
<Handle to holder, offset> pairs, then for each saved slot
re-internalize its string and update the slot to point to the
internalized string.
Bug: chromium:1011762
Change-Id: I008a694da3c357de34362bd86fe7e1f46b535d5e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1992434
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/heads/master@{#65787}
2020-01-15 11:47:41 +00:00
|
|
|
EXPECT_TRUE(string_1->IsInternalizedString());
|
|
|
|
EXPECT_EQ(*string_1, *string_2);
|
|
|
|
}
|
|
|
|
|
2020-08-13 12:12:17 +00:00
|
|
|
TEST_F(LocalFactoryTest, AstRawString_IsInternalized) {
|
2020-01-15 11:59:56 +00:00
|
|
|
AstValueFactory ast_value_factory(zone(), isolate()->ast_string_constants(),
|
|
|
|
HashSeed(isolate()));
|
|
|
|
|
|
|
|
const AstRawString* raw_string = ast_value_factory.GetOneByteString("foo");
|
|
|
|
|
2020-08-13 12:12:17 +00:00
|
|
|
Handle<String> string;
|
2020-02-28 12:24:46 +00:00
|
|
|
{
|
2020-08-13 12:12:17 +00:00
|
|
|
LocalHandleScope handle_scope(local_isolate());
|
2020-01-15 11:59:56 +00:00
|
|
|
|
2020-08-13 12:12:17 +00:00
|
|
|
ast_value_factory.Internalize(local_isolate());
|
2020-01-15 11:59:56 +00:00
|
|
|
|
2020-08-13 12:12:17 +00:00
|
|
|
string = local_isolate()->heap()->NewPersistentHandle(raw_string->string());
|
2020-02-28 12:24:46 +00:00
|
|
|
}
|
2020-01-15 11:59:56 +00:00
|
|
|
|
2021-06-17 15:43:55 +00:00
|
|
|
EXPECT_TRUE(string->IsOneByteEqualTo(base::CStrVector("foo")));
|
2020-01-15 11:59:56 +00:00
|
|
|
EXPECT_TRUE(string->IsInternalizedString());
|
|
|
|
}
|
|
|
|
|
2020-08-13 12:12:17 +00:00
|
|
|
TEST_F(LocalFactoryTest, AstConsString_CreatesConsString) {
|
2020-01-15 11:59:56 +00:00
|
|
|
AstValueFactory ast_value_factory(zone(), isolate()->ast_string_constants(),
|
|
|
|
HashSeed(isolate()));
|
|
|
|
|
2020-08-13 12:12:17 +00:00
|
|
|
Handle<String> string;
|
2020-02-28 12:24:46 +00:00
|
|
|
{
|
2020-08-13 12:12:17 +00:00
|
|
|
LocalHandleScope handle_scope(local_isolate());
|
2020-01-15 11:59:56 +00:00
|
|
|
|
2020-02-28 12:24:46 +00:00
|
|
|
const AstRawString* foo_string = ast_value_factory.GetOneByteString("foo");
|
|
|
|
const AstRawString* bar_string =
|
|
|
|
ast_value_factory.GetOneByteString("bar-plus-padding-for-length");
|
|
|
|
AstConsString* foobar_string =
|
|
|
|
ast_value_factory.NewConsString(foo_string, bar_string);
|
2020-01-15 11:59:56 +00:00
|
|
|
|
2020-08-13 12:12:17 +00:00
|
|
|
ast_value_factory.Internalize(local_isolate());
|
2020-01-15 11:59:56 +00:00
|
|
|
|
2020-08-13 12:12:17 +00:00
|
|
|
string = local_isolate()->heap()->NewPersistentHandle(
|
|
|
|
foobar_string->GetString(local_isolate()));
|
2020-02-28 12:24:46 +00:00
|
|
|
}
|
2020-01-15 11:59:56 +00:00
|
|
|
|
|
|
|
EXPECT_TRUE(string->IsConsString());
|
|
|
|
EXPECT_TRUE(string->Equals(*isolate()->factory()->NewStringFromStaticChars(
|
|
|
|
"foobar-plus-padding-for-length")));
|
|
|
|
}
|
|
|
|
|
2020-08-13 12:12:17 +00:00
|
|
|
TEST_F(LocalFactoryTest, EmptyScript) {
|
2020-02-13 09:39:04 +00:00
|
|
|
FunctionLiteral* program = ParseProgram("");
|
|
|
|
|
2020-08-13 12:12:17 +00:00
|
|
|
Handle<SharedFunctionInfo> shared;
|
2020-02-28 12:24:46 +00:00
|
|
|
{
|
2020-08-13 12:12:17 +00:00
|
|
|
LocalHandleScope handle_scope(local_isolate());
|
2020-02-13 09:39:04 +00:00
|
|
|
|
2020-08-13 12:12:17 +00:00
|
|
|
shared = local_isolate()->heap()->NewPersistentHandle(
|
|
|
|
local_factory()->NewSharedFunctionInfoForLiteral(program, script(),
|
|
|
|
true));
|
2020-02-28 12:24:46 +00:00
|
|
|
}
|
2020-08-13 12:12:17 +00:00
|
|
|
Handle<SharedFunctionInfo> root_sfi = shared;
|
2020-02-13 09:39:04 +00:00
|
|
|
|
|
|
|
EXPECT_EQ(root_sfi->function_literal_id(), 0);
|
|
|
|
}
|
|
|
|
|
2020-08-13 12:12:17 +00:00
|
|
|
TEST_F(LocalFactoryTest, LazyFunction) {
|
2020-02-13 09:39:04 +00:00
|
|
|
FunctionLiteral* program = ParseProgram("function lazy() {}");
|
|
|
|
FunctionLiteral* lazy = program->scope()
|
|
|
|
->declarations()
|
|
|
|
->AtForTest(0)
|
|
|
|
->AsFunctionDeclaration()
|
|
|
|
->fun();
|
|
|
|
|
2020-08-13 12:12:17 +00:00
|
|
|
Handle<SharedFunctionInfo> shared;
|
2020-02-28 12:24:46 +00:00
|
|
|
{
|
2020-08-13 12:12:17 +00:00
|
|
|
LocalHandleScope handle_scope(local_isolate());
|
2020-02-13 09:39:04 +00:00
|
|
|
|
2020-08-13 12:12:17 +00:00
|
|
|
shared = local_isolate()->heap()->NewPersistentHandle(
|
|
|
|
local_factory()->NewSharedFunctionInfoForLiteral(lazy, script(), true));
|
2020-02-28 12:24:46 +00:00
|
|
|
}
|
2020-08-13 12:12:17 +00:00
|
|
|
Handle<SharedFunctionInfo> lazy_sfi = shared;
|
2020-02-13 09:39:04 +00:00
|
|
|
|
|
|
|
EXPECT_EQ(lazy_sfi->function_literal_id(), 1);
|
2021-06-17 15:43:55 +00:00
|
|
|
EXPECT_TRUE(lazy_sfi->Name().IsOneByteEqualTo(base::CStrVector("lazy")));
|
2020-02-13 09:39:04 +00:00
|
|
|
EXPECT_FALSE(lazy_sfi->is_compiled());
|
|
|
|
EXPECT_TRUE(lazy_sfi->HasUncompiledDataWithoutPreparseData());
|
|
|
|
}
|
|
|
|
|
2020-08-13 12:12:17 +00:00
|
|
|
TEST_F(LocalFactoryTest, EagerFunction) {
|
2020-02-13 09:39:04 +00:00
|
|
|
FunctionLiteral* program = ParseProgram("(function eager() {})");
|
2020-05-05 16:27:30 +00:00
|
|
|
// Rewritten to `.result = (function eager() {}); return .result`
|
2020-02-13 09:39:04 +00:00
|
|
|
FunctionLiteral* eager = program->body()
|
|
|
|
->at(0)
|
|
|
|
->AsExpressionStatement()
|
|
|
|
->expression()
|
2020-05-05 16:27:30 +00:00
|
|
|
->AsAssignment()
|
|
|
|
->value()
|
2020-02-13 09:39:04 +00:00
|
|
|
->AsFunctionLiteral();
|
|
|
|
|
2020-08-13 12:12:17 +00:00
|
|
|
Handle<SharedFunctionInfo> shared;
|
2020-02-28 12:24:46 +00:00
|
|
|
{
|
2020-08-13 12:12:17 +00:00
|
|
|
LocalHandleScope handle_scope(local_isolate());
|
2020-02-28 12:24:46 +00:00
|
|
|
|
2020-08-13 12:12:17 +00:00
|
|
|
shared = local_isolate()->heap()->NewPersistentHandle(
|
|
|
|
local_factory()->NewSharedFunctionInfoForLiteral(eager, script(),
|
|
|
|
true));
|
2020-02-28 12:24:46 +00:00
|
|
|
}
|
2020-08-13 12:12:17 +00:00
|
|
|
Handle<SharedFunctionInfo> eager_sfi = shared;
|
2020-02-13 09:39:04 +00:00
|
|
|
|
|
|
|
EXPECT_EQ(eager_sfi->function_literal_id(), 1);
|
2021-06-17 15:43:55 +00:00
|
|
|
EXPECT_TRUE(eager_sfi->Name().IsOneByteEqualTo(base::CStrVector("eager")));
|
2020-02-13 09:39:04 +00:00
|
|
|
EXPECT_FALSE(eager_sfi->HasUncompiledData());
|
2020-08-13 12:12:17 +00:00
|
|
|
// TODO(leszeks): Add compilation support and enable these checks.
|
2020-02-13 09:39:04 +00:00
|
|
|
// EXPECT_TRUE(eager_sfi->is_compiled());
|
|
|
|
// EXPECT_TRUE(eager_sfi->HasBytecodeArray());
|
|
|
|
}
|
|
|
|
|
2020-08-13 12:12:17 +00:00
|
|
|
TEST_F(LocalFactoryTest, ImplicitNameFunction) {
|
2020-05-28 07:10:51 +00:00
|
|
|
FunctionLiteral* program = ParseProgram("let implicit_name = function() {}");
|
|
|
|
FunctionLiteral* implicit_name = program->body()
|
|
|
|
->at(0)
|
|
|
|
->AsBlock()
|
|
|
|
->statements()
|
|
|
|
->at(0)
|
|
|
|
->AsExpressionStatement()
|
|
|
|
->expression()
|
|
|
|
->AsAssignment()
|
|
|
|
->value()
|
|
|
|
->AsFunctionLiteral();
|
|
|
|
|
2020-08-13 12:12:17 +00:00
|
|
|
Handle<SharedFunctionInfo> shared;
|
2020-05-28 07:10:51 +00:00
|
|
|
{
|
2020-08-13 12:12:17 +00:00
|
|
|
LocalHandleScope handle_scope(local_isolate());
|
2020-05-28 07:10:51 +00:00
|
|
|
|
2020-08-13 12:12:17 +00:00
|
|
|
shared = local_isolate()->heap()->NewPersistentHandle(
|
|
|
|
local_factory()->NewSharedFunctionInfoForLiteral(implicit_name,
|
|
|
|
script(), true));
|
2020-05-28 07:10:51 +00:00
|
|
|
}
|
2020-08-13 12:12:17 +00:00
|
|
|
Handle<SharedFunctionInfo> implicit_name_sfi = shared;
|
2020-05-28 07:10:51 +00:00
|
|
|
|
|
|
|
EXPECT_EQ(implicit_name_sfi->function_literal_id(), 1);
|
2021-06-17 15:43:55 +00:00
|
|
|
EXPECT_TRUE(implicit_name_sfi->Name().IsOneByteEqualTo(
|
|
|
|
base::CStrVector("implicit_name")));
|
2020-05-28 07:10:51 +00:00
|
|
|
}
|
|
|
|
|
2020-08-13 12:12:17 +00:00
|
|
|
TEST_F(LocalFactoryTest, GCDuringPublish) {
|
2020-02-13 09:39:04 +00:00
|
|
|
FunctionLiteral* program = ParseProgram("let implicit_name = function() {}");
|
|
|
|
FunctionLiteral* implicit_name = program->body()
|
|
|
|
->at(0)
|
|
|
|
->AsBlock()
|
|
|
|
->statements()
|
|
|
|
->at(0)
|
|
|
|
->AsExpressionStatement()
|
|
|
|
->expression()
|
|
|
|
->AsAssignment()
|
|
|
|
->value()
|
|
|
|
->AsFunctionLiteral();
|
|
|
|
|
2020-08-13 12:12:17 +00:00
|
|
|
Handle<SharedFunctionInfo> shared;
|
2020-02-28 12:24:46 +00:00
|
|
|
{
|
2020-08-13 12:12:17 +00:00
|
|
|
LocalHandleScope handle_scope(local_isolate());
|
2020-02-13 09:39:04 +00:00
|
|
|
|
2020-08-13 12:12:17 +00:00
|
|
|
shared = local_isolate()->heap()->NewPersistentHandle(
|
|
|
|
local_factory()->NewSharedFunctionInfoForLiteral(implicit_name,
|
|
|
|
script(), true));
|
2020-02-28 12:24:46 +00:00
|
|
|
}
|
2020-08-13 12:12:17 +00:00
|
|
|
Handle<SharedFunctionInfo> implicit_name_sfi = shared;
|
2020-02-13 09:39:04 +00:00
|
|
|
|
|
|
|
EXPECT_EQ(implicit_name_sfi->function_literal_id(), 1);
|
2021-06-17 15:43:55 +00:00
|
|
|
EXPECT_TRUE(implicit_name_sfi->Name().IsOneByteEqualTo(
|
|
|
|
base::CStrVector("implicit_name")));
|
2020-02-13 09:39:04 +00:00
|
|
|
}
|
|
|
|
|
[offthread] Add OffThreadFactory
Introduce OffThreadFactory with initial string construction support.
The OffThreadFactory shares with Factory a new CRTP base class, called
FactoryBase. Methods in FactoryBase return a FactoryHandle<Factory, T>
alias, which is Handle<T> for normal Factory and a new OffThreadHandle<T>
for OffThreadFactory. OffThreadHandle<T> behaves like Handle<T>, except
it stores the object in-line rather than needing external storage.
Any shared factory methods are moved into FactoryBase, which uses CRTP
to call the sub-class's AllocateRaw method (plus a few more customization
points which need Isolate access on the main thread).
Methods that used to take an Isolate or Factory, and are needed off the
main thread, are now expected to be templated on the factory type and
to use the appropriate handle.
Once an OffThreadFactory has finished being used (e.g. off-thread
compilation completed) its pages are "Published" into the main-thread
Heap. To deal with string internalization without creating a bunch of
ThinStrings, this is done in two stages:
1. 'FinishOffThread': The off-thread pages are walked to
collect all slots pointing to "internalized" strings. After this is
called it is invalid to allocate any more objects with the factory.
2. 'Publish': On the main thread, we transform these slots into
<Handle to holder, offset> pairs, then for each saved slot
re-internalize its string and update the slot to point to the
internalized string.
Bug: chromium:1011762
Change-Id: I008a694da3c357de34362bd86fe7e1f46b535d5e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1992434
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/heads/master@{#65787}
2020-01-15 11:47:41 +00:00
|
|
|
} // namespace internal
|
|
|
|
} // namespace v8
|