2017-09-16 05:22:38 +00:00
|
|
|
// Copyright 2017 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 "test/unittests/test-utils.h"
|
|
|
|
#include "testing/gmock/include/gmock/gmock.h"
|
|
|
|
|
2018-04-24 13:10:51 +00:00
|
|
|
#include "src/wasm/function-compiler.h"
|
2018-06-19 09:47:17 +00:00
|
|
|
#include "src/wasm/jump-table-assembler.h"
|
2017-12-05 01:47:59 +00:00
|
|
|
#include "src/wasm/wasm-code-manager.h"
|
2018-10-25 13:29:13 +00:00
|
|
|
#include "src/wasm/wasm-engine.h"
|
2018-09-18 13:05:45 +00:00
|
|
|
#include "src/wasm/wasm-memory.h"
|
2017-09-16 05:22:38 +00:00
|
|
|
|
|
|
|
namespace v8 {
|
|
|
|
namespace internal {
|
|
|
|
namespace wasm {
|
2017-09-28 17:55:52 +00:00
|
|
|
namespace wasm_heap_unittest {
|
2017-09-16 05:22:38 +00:00
|
|
|
|
2017-09-28 17:55:52 +00:00
|
|
|
class DisjointAllocationPoolTest : public ::testing::Test {
|
2017-09-16 05:22:38 +00:00
|
|
|
public:
|
2018-09-24 13:25:40 +00:00
|
|
|
void CheckPool(const DisjointAllocationPool& mem,
|
2018-09-25 14:21:11 +00:00
|
|
|
std::initializer_list<base::AddressRegion> expected_regions);
|
|
|
|
void CheckRange(base::AddressRegion region1, base::AddressRegion region2);
|
|
|
|
DisjointAllocationPool Make(
|
|
|
|
std::initializer_list<base::AddressRegion> regions);
|
2017-09-16 05:22:38 +00:00
|
|
|
};
|
|
|
|
|
2018-09-24 13:25:40 +00:00
|
|
|
void DisjointAllocationPoolTest::CheckPool(
|
2017-09-16 05:22:38 +00:00
|
|
|
const DisjointAllocationPool& mem,
|
2018-09-25 14:21:11 +00:00
|
|
|
std::initializer_list<base::AddressRegion> expected_regions) {
|
|
|
|
const auto& regions = mem.regions();
|
|
|
|
CHECK_EQ(regions.size(), expected_regions.size());
|
|
|
|
auto iter = expected_regions.begin();
|
|
|
|
for (auto it = regions.begin(), e = regions.end(); it != e; ++it, ++iter) {
|
2018-09-24 13:25:40 +00:00
|
|
|
CHECK_EQ(*it, *iter);
|
2017-09-16 05:22:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-25 14:21:11 +00:00
|
|
|
void DisjointAllocationPoolTest::CheckRange(base::AddressRegion region1,
|
|
|
|
base::AddressRegion region2) {
|
|
|
|
CHECK_EQ(region1, region2);
|
2018-06-08 11:05:58 +00:00
|
|
|
}
|
|
|
|
|
2017-09-16 05:22:38 +00:00
|
|
|
DisjointAllocationPool DisjointAllocationPoolTest::Make(
|
2018-09-25 14:21:11 +00:00
|
|
|
std::initializer_list<base::AddressRegion> regions) {
|
2017-09-16 05:22:38 +00:00
|
|
|
DisjointAllocationPool ret;
|
2018-09-25 14:21:11 +00:00
|
|
|
for (auto& region : regions) {
|
|
|
|
ret.Merge(region);
|
2017-09-16 05:22:38 +00:00
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2018-06-08 11:05:58 +00:00
|
|
|
TEST_F(DisjointAllocationPoolTest, ConstructEmpty) {
|
2017-09-16 05:22:38 +00:00
|
|
|
DisjointAllocationPool a;
|
|
|
|
CHECK(a.IsEmpty());
|
2018-09-24 13:25:40 +00:00
|
|
|
CheckPool(a, {});
|
2018-09-25 14:21:11 +00:00
|
|
|
a.Merge({1, 4});
|
|
|
|
CheckPool(a, {{1, 4}});
|
2018-06-08 11:05:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(DisjointAllocationPoolTest, ConstructWithRange) {
|
2018-09-25 14:21:11 +00:00
|
|
|
DisjointAllocationPool a({1, 4});
|
2018-06-08 11:05:58 +00:00
|
|
|
CHECK(!a.IsEmpty());
|
2018-09-25 14:21:11 +00:00
|
|
|
CheckPool(a, {{1, 4}});
|
2017-09-16 05:22:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(DisjointAllocationPoolTest, SimpleExtract) {
|
2018-09-25 14:21:11 +00:00
|
|
|
DisjointAllocationPool a = Make({{1, 4}});
|
|
|
|
base::AddressRegion b = a.Allocate(2);
|
|
|
|
CheckPool(a, {{3, 2}});
|
|
|
|
CheckRange(b, {1, 2});
|
2018-06-08 11:05:58 +00:00
|
|
|
a.Merge(b);
|
2018-09-25 14:21:11 +00:00
|
|
|
CheckPool(a, {{1, 4}});
|
|
|
|
CHECK_EQ(a.regions().size(), 1);
|
|
|
|
CHECK_EQ(a.regions().front().begin(), 1);
|
|
|
|
CHECK_EQ(a.regions().front().end(), 5);
|
2017-09-16 05:22:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(DisjointAllocationPoolTest, ExtractAll) {
|
2018-09-25 14:21:11 +00:00
|
|
|
DisjointAllocationPool a({1, 4});
|
|
|
|
base::AddressRegion b = a.Allocate(4);
|
|
|
|
CheckRange(b, {1, 4});
|
2017-09-16 05:22:38 +00:00
|
|
|
CHECK(a.IsEmpty());
|
2018-06-08 11:05:58 +00:00
|
|
|
a.Merge(b);
|
2018-09-25 14:21:11 +00:00
|
|
|
CheckPool(a, {{1, 4}});
|
2017-09-16 05:22:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(DisjointAllocationPoolTest, FailToExtract) {
|
2018-09-25 14:21:11 +00:00
|
|
|
DisjointAllocationPool a = Make({{1, 4}});
|
|
|
|
base::AddressRegion b = a.Allocate(5);
|
|
|
|
CheckPool(a, {{1, 4}});
|
2018-06-08 11:05:58 +00:00
|
|
|
CHECK(b.is_empty());
|
2017-09-16 05:22:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(DisjointAllocationPoolTest, FailToExtractExact) {
|
2018-09-25 14:21:11 +00:00
|
|
|
DisjointAllocationPool a = Make({{1, 4}, {10, 4}});
|
|
|
|
base::AddressRegion b = a.Allocate(5);
|
|
|
|
CheckPool(a, {{1, 4}, {10, 4}});
|
2018-06-08 11:05:58 +00:00
|
|
|
CHECK(b.is_empty());
|
2017-09-16 05:22:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(DisjointAllocationPoolTest, ExtractExact) {
|
2018-09-25 14:21:11 +00:00
|
|
|
DisjointAllocationPool a = Make({{1, 4}, {10, 5}});
|
|
|
|
base::AddressRegion b = a.Allocate(5);
|
|
|
|
CheckPool(a, {{1, 4}});
|
|
|
|
CheckRange(b, {10, 5});
|
2017-09-16 05:22:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(DisjointAllocationPoolTest, Merging) {
|
2018-09-25 14:21:11 +00:00
|
|
|
DisjointAllocationPool a = Make({{10, 5}, {20, 5}});
|
|
|
|
a.Merge({15, 5});
|
|
|
|
CheckPool(a, {{10, 15}});
|
2017-09-16 05:22:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(DisjointAllocationPoolTest, MergingMore) {
|
2018-09-25 14:21:11 +00:00
|
|
|
DisjointAllocationPool a = Make({{10, 5}, {20, 5}, {30, 5}});
|
|
|
|
a.Merge({15, 5});
|
|
|
|
a.Merge({25, 5});
|
|
|
|
CheckPool(a, {{10, 25}});
|
2017-09-16 05:22:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(DisjointAllocationPoolTest, MergingSkip) {
|
2018-09-25 14:21:11 +00:00
|
|
|
DisjointAllocationPool a = Make({{10, 5}, {20, 5}, {30, 5}});
|
|
|
|
a.Merge({25, 5});
|
|
|
|
CheckPool(a, {{10, 5}, {20, 15}});
|
2017-09-16 05:22:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(DisjointAllocationPoolTest, MergingSkipLargerSrc) {
|
2018-09-25 14:21:11 +00:00
|
|
|
DisjointAllocationPool a = Make({{10, 5}, {20, 5}, {30, 5}});
|
|
|
|
a.Merge({25, 5});
|
|
|
|
a.Merge({35, 5});
|
|
|
|
CheckPool(a, {{10, 5}, {20, 20}});
|
2017-09-16 05:22:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(DisjointAllocationPoolTest, MergingSkipLargerSrcWithGap) {
|
2018-09-25 14:21:11 +00:00
|
|
|
DisjointAllocationPool a = Make({{10, 5}, {20, 5}, {30, 5}});
|
|
|
|
a.Merge({25, 5});
|
|
|
|
a.Merge({36, 4});
|
|
|
|
CheckPool(a, {{10, 5}, {20, 15}, {36, 4}});
|
2017-09-16 05:22:38 +00:00
|
|
|
}
|
|
|
|
|
2018-03-19 12:34:59 +00:00
|
|
|
enum ModuleStyle : int { Fixed = 0, Growable = 1 };
|
|
|
|
|
2018-06-20 11:19:45 +00:00
|
|
|
std::string PrintWasmCodeManageTestParam(
|
|
|
|
::testing::TestParamInfo<ModuleStyle> info) {
|
|
|
|
switch (info.param) {
|
|
|
|
case Fixed:
|
|
|
|
return "Fixed";
|
|
|
|
case Growable:
|
|
|
|
return "Growable";
|
|
|
|
}
|
|
|
|
UNREACHABLE();
|
|
|
|
}
|
|
|
|
|
2018-03-19 12:34:59 +00:00
|
|
|
class WasmCodeManagerTest : public TestWithContext,
|
|
|
|
public ::testing::WithParamInterface<ModuleStyle> {
|
2017-11-20 21:34:04 +00:00
|
|
|
public:
|
2018-06-19 09:47:17 +00:00
|
|
|
static constexpr uint32_t kNumFunctions = 10;
|
|
|
|
static constexpr uint32_t kJumpTableSize = RoundUp<kCodeAlignment>(
|
2018-08-07 10:33:50 +00:00
|
|
|
JumpTableAssembler::SizeForNumberOfSlots(kNumFunctions));
|
2018-06-19 09:47:17 +00:00
|
|
|
|
2019-03-12 16:10:58 +00:00
|
|
|
using NativeModulePtr = std::shared_ptr<NativeModule>;
|
2017-11-20 21:34:04 +00:00
|
|
|
|
2018-10-25 13:29:13 +00:00
|
|
|
NativeModulePtr AllocModule(size_t size, ModuleStyle style) {
|
2018-06-28 13:23:24 +00:00
|
|
|
std::shared_ptr<WasmModule> module(new WasmModule);
|
|
|
|
module->num_declared_functions = kNumFunctions;
|
2018-06-12 16:43:02 +00:00
|
|
|
bool can_request_more = style == Growable;
|
2019-01-25 10:35:37 +00:00
|
|
|
return engine()->NewNativeModule(i_isolate(), kAllWasmFeatures, size,
|
|
|
|
can_request_more, std::move(module));
|
2017-11-20 21:34:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
WasmCode* AddCode(NativeModule* native_module, uint32_t index, size_t size) {
|
|
|
|
CodeDesc desc;
|
|
|
|
memset(reinterpret_cast<void*>(&desc), 0, sizeof(CodeDesc));
|
|
|
|
std::unique_ptr<byte[]> exec_buff(new byte[size]);
|
|
|
|
desc.buffer = exec_buff.get();
|
|
|
|
desc.instr_size = static_cast<int>(size);
|
[wasm] Split adding code from publishing it
This prepares a refactoring to add and publish compilation results in
batches. For this, we need to separate the two phases, so that we can
lock the module, allocate all the code space, release the lock, copy
the code, lock the module, publish the code, and release the lock
again.
In particular, this CL does the following:
1) It removes the {AddOwnedCode} method. The functionality of creating
the {WasmCode} and memcpy'ing the instruction into that is done in
the other {Add*Code} methods. Adding to {owned_code_} is done in
{PublishCode}.
2) {PublishInterpreterEntry} is now functionally equivalent to
{PublishCode}, so it's removed.
3) After {AddCode}, the caller has to call {PublishCode}. In a
follow-up CL, this will be called in batches (first {AddCode} them
all, then {PublishCode} them all).
4) {AddCompiledCode} now assumes that the {WasmCompilationResult}
succeeded. Otherwise, the caller should directly call {SetError} on
the {CompilationState}.
5) {PublishCode} is now the chokepoint for installing code to the code
table, the owned code vector, the jump table, and setting interpreter
redirections. It replaces previous direct calls to {InstallCode} or
explicitly adding to {owned_code_}.
6) Increasing the {generated_code_size_} counter is now done in
{AllocateForCode}, which is the chokepoint for allocating space for
generated code. This way, we will only increase this counter once
once we allocate in batches.
R=titzer@chromium.org
Bug: v8:8916
Change-Id: I71e02e3a838f21797915cee3ebd373804fb12237
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1530817
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Reviewed-by: Ben Titzer <titzer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#60369}
2019-03-20 13:04:33 +00:00
|
|
|
std::unique_ptr<WasmCode> code = native_module->AddCode(
|
2019-04-03 15:37:47 +00:00
|
|
|
index, desc, 0, 0, {}, {}, WasmCode::kFunction, ExecutionTier::kNone);
|
2019-04-05 10:36:06 +00:00
|
|
|
return native_module->PublishCode(std::move(code));
|
2017-11-20 21:34:04 +00:00
|
|
|
}
|
|
|
|
|
2017-12-15 17:59:57 +00:00
|
|
|
size_t page() const { return AllocatePageSize(); }
|
2018-09-18 13:05:45 +00:00
|
|
|
|
2019-01-25 10:35:37 +00:00
|
|
|
WasmEngine* engine() { return i_isolate()->wasm_engine(); }
|
|
|
|
|
|
|
|
WasmCodeManager* manager() { return engine()->code_manager(); }
|
2018-09-18 13:05:45 +00:00
|
|
|
|
2018-10-25 13:29:13 +00:00
|
|
|
void SetMaxCommittedMemory(size_t limit) {
|
|
|
|
manager()->SetMaxCommittedMemoryForTesting(limit);
|
|
|
|
}
|
2017-11-20 21:34:04 +00:00
|
|
|
};
|
|
|
|
|
2019-02-15 16:53:29 +00:00
|
|
|
INSTANTIATE_TEST_SUITE_P(Parameterized, WasmCodeManagerTest,
|
|
|
|
::testing::Values(Fixed, Growable),
|
|
|
|
PrintWasmCodeManageTestParam);
|
2018-03-19 12:34:59 +00:00
|
|
|
|
|
|
|
TEST_P(WasmCodeManagerTest, EmptyCase) {
|
2018-10-25 13:29:13 +00:00
|
|
|
SetMaxCommittedMemory(0 * page());
|
|
|
|
CHECK_EQ(0, manager()->remaining_uncommitted_code_space());
|
2018-03-19 12:34:59 +00:00
|
|
|
|
2018-10-25 13:29:13 +00:00
|
|
|
ASSERT_DEATH_IF_SUPPORTED(AllocModule(1 * page(), GetParam()),
|
2018-09-27 09:20:06 +00:00
|
|
|
"OOM in NativeModule::AllocateForCode commit");
|
2017-11-20 21:34:04 +00:00
|
|
|
}
|
|
|
|
|
2018-03-19 12:34:59 +00:00
|
|
|
TEST_P(WasmCodeManagerTest, AllocateAndGoOverLimit) {
|
2018-10-25 13:29:13 +00:00
|
|
|
SetMaxCommittedMemory(1 * page());
|
|
|
|
CHECK_EQ(1 * page(), manager()->remaining_uncommitted_code_space());
|
|
|
|
NativeModulePtr native_module = AllocModule(1 * page(), GetParam());
|
2018-03-19 12:34:59 +00:00
|
|
|
CHECK(native_module);
|
2018-10-25 13:29:13 +00:00
|
|
|
CHECK_EQ(0, manager()->remaining_uncommitted_code_space());
|
2019-04-02 10:41:00 +00:00
|
|
|
WasmCodeRefScope code_ref_scope;
|
2018-03-19 12:34:59 +00:00
|
|
|
uint32_t index = 0;
|
|
|
|
WasmCode* code = AddCode(native_module.get(), index++, 1 * kCodeAlignment);
|
|
|
|
CHECK_NOT_NULL(code);
|
2018-10-25 13:29:13 +00:00
|
|
|
CHECK_EQ(0, manager()->remaining_uncommitted_code_space());
|
2018-03-19 12:34:59 +00:00
|
|
|
|
|
|
|
code = AddCode(native_module.get(), index++, 3 * kCodeAlignment);
|
|
|
|
CHECK_NOT_NULL(code);
|
2018-10-25 13:29:13 +00:00
|
|
|
CHECK_EQ(0, manager()->remaining_uncommitted_code_space());
|
2018-03-19 12:34:59 +00:00
|
|
|
|
2018-06-19 09:47:17 +00:00
|
|
|
code = AddCode(native_module.get(), index++,
|
|
|
|
page() - 4 * kCodeAlignment - kJumpTableSize);
|
2018-03-19 12:34:59 +00:00
|
|
|
CHECK_NOT_NULL(code);
|
2018-10-25 13:29:13 +00:00
|
|
|
CHECK_EQ(0, manager()->remaining_uncommitted_code_space());
|
2018-03-19 12:34:59 +00:00
|
|
|
|
2018-09-27 09:20:06 +00:00
|
|
|
// This fails in "reservation" if we cannot extend the code space, or in
|
|
|
|
// "commit" it we can (since we hit the allocation limit in the
|
|
|
|
// WasmCodeManager). Hence don't check for that part of the OOM message.
|
2018-03-19 12:34:59 +00:00
|
|
|
ASSERT_DEATH_IF_SUPPORTED(
|
|
|
|
AddCode(native_module.get(), index++, 1 * kCodeAlignment),
|
2018-09-27 09:20:06 +00:00
|
|
|
"OOM in NativeModule::AllocateForCode");
|
2017-11-20 21:34:04 +00:00
|
|
|
}
|
|
|
|
|
2018-03-19 12:34:59 +00:00
|
|
|
TEST_P(WasmCodeManagerTest, TotalLimitIrrespectiveOfModuleCount) {
|
2018-10-25 13:29:13 +00:00
|
|
|
SetMaxCommittedMemory(3 * page());
|
|
|
|
NativeModulePtr nm1 = AllocModule(2 * page(), GetParam());
|
|
|
|
NativeModulePtr nm2 = AllocModule(2 * page(), GetParam());
|
2018-03-19 12:34:59 +00:00
|
|
|
CHECK(nm1);
|
|
|
|
CHECK(nm2);
|
2019-04-02 10:41:00 +00:00
|
|
|
WasmCodeRefScope code_ref_scope;
|
2018-06-19 09:47:17 +00:00
|
|
|
WasmCode* code = AddCode(nm1.get(), 0, 2 * page() - kJumpTableSize);
|
2018-03-19 12:34:59 +00:00
|
|
|
CHECK_NOT_NULL(code);
|
2018-06-19 09:47:17 +00:00
|
|
|
ASSERT_DEATH_IF_SUPPORTED(AddCode(nm2.get(), 0, 2 * page() - kJumpTableSize),
|
2018-09-27 09:20:06 +00:00
|
|
|
"OOM in NativeModule::AllocateForCode commit");
|
2017-11-20 21:34:04 +00:00
|
|
|
}
|
|
|
|
|
2018-03-19 12:34:59 +00:00
|
|
|
TEST_P(WasmCodeManagerTest, GrowingVsFixedModule) {
|
2018-10-25 13:29:13 +00:00
|
|
|
SetMaxCommittedMemory(3 * page());
|
|
|
|
NativeModulePtr nm = AllocModule(1 * page(), GetParam());
|
2018-06-20 11:19:45 +00:00
|
|
|
size_t module_size = GetParam() == Fixed ? kMaxWasmCodeMemory : 1 * page();
|
|
|
|
size_t remaining_space_in_module = module_size - kJumpTableSize;
|
2018-03-19 12:34:59 +00:00
|
|
|
if (GetParam() == Fixed) {
|
2018-06-20 11:19:45 +00:00
|
|
|
// Requesting more than the remaining space fails because the module cannot
|
|
|
|
// grow.
|
|
|
|
ASSERT_DEATH_IF_SUPPORTED(
|
|
|
|
AddCode(nm.get(), 0, remaining_space_in_module + kCodeAlignment),
|
2018-09-27 09:20:06 +00:00
|
|
|
"OOM in NativeModule::AllocateForCode");
|
2018-03-19 12:34:59 +00:00
|
|
|
} else {
|
2018-06-20 11:19:45 +00:00
|
|
|
// The module grows by one page. One page remains uncommitted.
|
2019-04-02 10:41:00 +00:00
|
|
|
WasmCodeRefScope code_ref_scope;
|
2018-06-20 11:19:45 +00:00
|
|
|
CHECK_NOT_NULL(
|
|
|
|
AddCode(nm.get(), 0, remaining_space_in_module + kCodeAlignment));
|
2018-10-25 13:29:13 +00:00
|
|
|
CHECK_EQ(manager()->remaining_uncommitted_code_space(), 1 * page());
|
2017-11-20 21:34:04 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-03-19 12:34:59 +00:00
|
|
|
TEST_P(WasmCodeManagerTest, CommitIncrements) {
|
2018-10-25 13:29:13 +00:00
|
|
|
SetMaxCommittedMemory(10 * page());
|
|
|
|
NativeModulePtr nm = AllocModule(3 * page(), GetParam());
|
2019-04-02 10:41:00 +00:00
|
|
|
WasmCodeRefScope code_ref_scope;
|
2018-03-19 12:34:59 +00:00
|
|
|
WasmCode* code = AddCode(nm.get(), 0, kCodeAlignment);
|
|
|
|
CHECK_NOT_NULL(code);
|
2018-10-25 13:29:13 +00:00
|
|
|
CHECK_EQ(manager()->remaining_uncommitted_code_space(), 9 * page());
|
2018-03-19 12:34:59 +00:00
|
|
|
code = AddCode(nm.get(), 1, 2 * page());
|
|
|
|
CHECK_NOT_NULL(code);
|
2018-10-25 13:29:13 +00:00
|
|
|
CHECK_EQ(manager()->remaining_uncommitted_code_space(), 7 * page());
|
2018-06-19 09:47:17 +00:00
|
|
|
code = AddCode(nm.get(), 2, page() - kCodeAlignment - kJumpTableSize);
|
2018-03-19 12:34:59 +00:00
|
|
|
CHECK_NOT_NULL(code);
|
2018-10-25 13:29:13 +00:00
|
|
|
CHECK_EQ(manager()->remaining_uncommitted_code_space(), 7 * page());
|
2017-11-20 21:34:04 +00:00
|
|
|
}
|
|
|
|
|
2018-03-19 12:34:59 +00:00
|
|
|
TEST_P(WasmCodeManagerTest, Lookup) {
|
2018-10-25 13:29:13 +00:00
|
|
|
SetMaxCommittedMemory(2 * page());
|
2018-03-19 12:34:59 +00:00
|
|
|
|
2018-10-25 13:29:13 +00:00
|
|
|
NativeModulePtr nm1 = AllocModule(1 * page(), GetParam());
|
|
|
|
NativeModulePtr nm2 = AllocModule(1 * page(), GetParam());
|
2019-04-02 10:41:00 +00:00
|
|
|
Address mid_code1_1;
|
|
|
|
{
|
|
|
|
// The {WasmCodeRefScope} needs to die before {nm1} dies.
|
|
|
|
WasmCodeRefScope code_ref_scope;
|
|
|
|
WasmCode* code1_0 = AddCode(nm1.get(), 0, kCodeAlignment);
|
|
|
|
CHECK_EQ(nm1.get(), code1_0->native_module());
|
|
|
|
WasmCode* code1_1 = AddCode(nm1.get(), 1, kCodeAlignment);
|
|
|
|
WasmCode* code2_0 = AddCode(nm2.get(), 0, kCodeAlignment);
|
|
|
|
WasmCode* code2_1 = AddCode(nm2.get(), 1, kCodeAlignment);
|
|
|
|
CHECK_EQ(nm2.get(), code2_1->native_module());
|
|
|
|
|
|
|
|
CHECK_EQ(0, code1_0->index());
|
|
|
|
CHECK_EQ(1, code1_1->index());
|
|
|
|
CHECK_EQ(0, code2_0->index());
|
|
|
|
CHECK_EQ(1, code2_1->index());
|
|
|
|
|
|
|
|
// we know the manager object is allocated here, so we shouldn't
|
|
|
|
// find any WasmCode* associated with that ptr.
|
|
|
|
WasmCode* not_found =
|
|
|
|
manager()->LookupCode(reinterpret_cast<Address>(manager()));
|
|
|
|
CHECK_NULL(not_found);
|
|
|
|
WasmCode* found = manager()->LookupCode(code1_0->instruction_start());
|
|
|
|
CHECK_EQ(found, code1_0);
|
|
|
|
found = manager()->LookupCode(code2_1->instruction_start() +
|
|
|
|
(code2_1->instructions().size() / 2));
|
|
|
|
CHECK_EQ(found, code2_1);
|
|
|
|
found = manager()->LookupCode(code2_1->instruction_start() +
|
|
|
|
code2_1->instructions().size() - 1);
|
|
|
|
CHECK_EQ(found, code2_1);
|
|
|
|
found = manager()->LookupCode(code2_1->instruction_start() +
|
|
|
|
code2_1->instructions().size());
|
|
|
|
CHECK_NULL(found);
|
|
|
|
mid_code1_1 =
|
|
|
|
code1_1->instruction_start() + (code1_1->instructions().size() / 2);
|
|
|
|
CHECK_EQ(code1_1, manager()->LookupCode(mid_code1_1));
|
|
|
|
}
|
2018-03-19 12:34:59 +00:00
|
|
|
nm1.reset();
|
2018-10-25 13:29:13 +00:00
|
|
|
CHECK_NULL(manager()->LookupCode(mid_code1_1));
|
2017-11-20 21:34:04 +00:00
|
|
|
}
|
|
|
|
|
2018-03-19 12:34:59 +00:00
|
|
|
TEST_P(WasmCodeManagerTest, LookupWorksAfterRewrite) {
|
2018-10-25 13:29:13 +00:00
|
|
|
SetMaxCommittedMemory(2 * page());
|
2018-03-19 12:34:59 +00:00
|
|
|
|
2018-10-25 13:29:13 +00:00
|
|
|
NativeModulePtr nm1 = AllocModule(1 * page(), GetParam());
|
2018-03-19 12:34:59 +00:00
|
|
|
|
2019-04-02 10:41:00 +00:00
|
|
|
WasmCodeRefScope code_ref_scope;
|
2018-03-19 12:34:59 +00:00
|
|
|
WasmCode* code0 = AddCode(nm1.get(), 0, kCodeAlignment);
|
|
|
|
WasmCode* code1 = AddCode(nm1.get(), 1, kCodeAlignment);
|
|
|
|
CHECK_EQ(0, code0->index());
|
|
|
|
CHECK_EQ(1, code1->index());
|
2018-10-25 13:29:13 +00:00
|
|
|
CHECK_EQ(code1, manager()->LookupCode(code1->instruction_start()));
|
2018-03-19 12:34:59 +00:00
|
|
|
WasmCode* code1_1 = AddCode(nm1.get(), 1, kCodeAlignment);
|
|
|
|
CHECK_EQ(1, code1_1->index());
|
2018-10-25 13:29:13 +00:00
|
|
|
CHECK_EQ(code1, manager()->LookupCode(code1->instruction_start()));
|
|
|
|
CHECK_EQ(code1_1, manager()->LookupCode(code1_1->instruction_start()));
|
2017-11-20 21:34:04 +00:00
|
|
|
}
|
|
|
|
|
2017-09-28 17:55:52 +00:00
|
|
|
} // namespace wasm_heap_unittest
|
2017-09-16 05:22:38 +00:00
|
|
|
} // namespace wasm
|
|
|
|
} // namespace internal
|
|
|
|
} // namespace v8
|