c51041f454
With the new Turbofan variants (NCI and Turboprop), we need a way to distinguish between them both during and after compilation. We initially introduced CompilationTarget to track the variant during compilation, but decided to reuse the code kind as the canonical spot to store this information instead. Why? Because it is an established mechanism, already available in most of the necessary spots (inside the pipeline, on Code objects, in profiling traces). This CL removes CompilationTarget and adds a new NATIVE_CONTEXT_INDEPENDENT kind, plus helper functions to determine various things about a given code kind (e.g.: does this code kind deopt?). As a (very large) drive-by, refactor both Code::Kind and AbstractCode::Kind into a new CodeKind enum class. Bug: v8:8888 Change-Id: Ie858b9a53311b0731630be35cf5cd108dee95b39 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2336793 Commit-Queue: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Clemens Backes <clemensb@chromium.org> Reviewed-by: Ross McIlroy <rmcilroy@chromium.org> Reviewed-by: Dominik Inführ <dinfuehr@chromium.org> Reviewed-by: Georg Neis <neis@chromium.org> Cr-Commit-Position: refs/heads/master@{#69244}
120 lines
3.6 KiB
C++
120 lines
3.6 KiB
C++
// Copyright 2018 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 <memory>
|
|
|
|
#include "include/v8.h"
|
|
|
|
#include "src/codegen/code-desc.h"
|
|
#include "src/execution/isolate.h"
|
|
#include "src/handles/handles-inl.h"
|
|
#include "test/cctest/cctest.h"
|
|
|
|
namespace v8 {
|
|
namespace internal {
|
|
namespace test_factory {
|
|
|
|
namespace {
|
|
|
|
// This needs to be large enough to create a new nosnap Isolate, but smaller
|
|
// than kMaximalCodeRangeSize so we can recover from the OOM.
|
|
constexpr int kInstructionSize = 100 * MB;
|
|
STATIC_ASSERT(kInstructionSize < kMaximalCodeRangeSize ||
|
|
!kPlatformRequiresCodeRange);
|
|
|
|
size_t NearHeapLimitCallback(void* raw_bool, size_t current_heap_limit,
|
|
size_t initial_heap_limit) {
|
|
bool* oom_triggered = static_cast<bool*>(raw_bool);
|
|
*oom_triggered = true;
|
|
return kInstructionSize * 2;
|
|
}
|
|
|
|
class SetupIsolateWithSmallHeap {
|
|
public:
|
|
SetupIsolateWithSmallHeap() {
|
|
FLAG_max_old_space_size = kInstructionSize / MB / 2; // In MB.
|
|
v8::Isolate::CreateParams create_params;
|
|
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
|
|
isolate_ = reinterpret_cast<Isolate*>(v8::Isolate::New(create_params));
|
|
isolate_->heap()->AddNearHeapLimitCallback(NearHeapLimitCallback,
|
|
&oom_triggered_);
|
|
}
|
|
|
|
~SetupIsolateWithSmallHeap() {
|
|
reinterpret_cast<v8::Isolate*>(isolate_)->Dispose();
|
|
}
|
|
|
|
Isolate* isolate() { return isolate_; }
|
|
bool oom_triggered() const { return oom_triggered_; }
|
|
|
|
private:
|
|
Isolate* isolate_;
|
|
bool oom_triggered_ = false;
|
|
};
|
|
|
|
} // namespace
|
|
|
|
TEST(Factory_CodeBuilder) {
|
|
Isolate* isolate = CcTest::i_isolate();
|
|
HandleScope scope(isolate);
|
|
|
|
// Create a big function that ends up in CODE_LO_SPACE.
|
|
const int instruction_size = kMaxRegularHeapObjectSize + 1;
|
|
std::unique_ptr<byte[]> instructions(new byte[instruction_size]);
|
|
|
|
CodeDesc desc;
|
|
desc.buffer = instructions.get();
|
|
desc.buffer_size = instruction_size;
|
|
desc.instr_size = instruction_size;
|
|
desc.reloc_size = 0;
|
|
desc.constant_pool_size = 0;
|
|
desc.unwinding_info = nullptr;
|
|
desc.unwinding_info_size = 0;
|
|
desc.origin = nullptr;
|
|
Handle<Code> code =
|
|
Factory::CodeBuilder(isolate, desc, CodeKind::WASM_FUNCTION).Build();
|
|
|
|
CHECK(isolate->heap()->InSpace(*code, CODE_LO_SPACE));
|
|
#if VERIFY_HEAP
|
|
code->ObjectVerify(isolate);
|
|
#endif
|
|
}
|
|
|
|
UNINITIALIZED_TEST(Factory_CodeBuilder_BuildOOM) {
|
|
SetupIsolateWithSmallHeap isolate_scope;
|
|
HandleScope scope(isolate_scope.isolate());
|
|
std::unique_ptr<byte[]> instructions(new byte[kInstructionSize]);
|
|
CodeDesc desc;
|
|
desc.instr_size = kInstructionSize;
|
|
desc.buffer = instructions.get();
|
|
|
|
const Handle<Code> code = Factory::CodeBuilder(isolate_scope.isolate(), desc,
|
|
CodeKind::WASM_FUNCTION)
|
|
.Build();
|
|
|
|
CHECK(!code.is_null());
|
|
CHECK(isolate_scope.oom_triggered());
|
|
}
|
|
|
|
UNINITIALIZED_TEST(Factory_CodeBuilder_TryBuildOOM) {
|
|
SetupIsolateWithSmallHeap isolate_scope;
|
|
HandleScope scope(isolate_scope.isolate());
|
|
std::unique_ptr<byte[]> instructions(new byte[kInstructionSize]);
|
|
CodeDesc desc;
|
|
desc.instr_size = kInstructionSize;
|
|
desc.buffer = instructions.get();
|
|
|
|
const MaybeHandle<Code> code =
|
|
Factory::CodeBuilder(isolate_scope.isolate(), desc,
|
|
CodeKind::WASM_FUNCTION)
|
|
.TryBuild();
|
|
|
|
CHECK(code.is_null());
|
|
CHECK(!isolate_scope.oom_triggered());
|
|
}
|
|
|
|
} // namespace test_factory
|
|
} // namespace internal
|
|
} // namespace v8
|