2022-09-01 14:11:31 +00:00
|
|
|
// Copyright 2022 the V8 project authors. All rights reserved.
|
2016-06-17 13:19:58 +00:00
|
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
|
|
// found in the LICENSE file.
|
|
|
|
|
2022-09-01 14:11:31 +00:00
|
|
|
#ifndef V8_TEST_COMMON_CODE_ASSEMBLER_TESTER_H_
|
|
|
|
#define V8_TEST_COMMON_CODE_ASSEMBLER_TESTER_H_
|
2017-09-21 02:04:27 +00:00
|
|
|
|
2022-07-07 11:52:08 +00:00
|
|
|
#include "src/codegen/assembler.h"
|
2016-06-17 13:19:58 +00:00
|
|
|
#include "src/codegen/interface-descriptors.h"
|
2016-11-16 11:48:07 +00:00
|
|
|
#include "src/compiler/code-assembler.h"
|
2017-10-11 10:22:40 +00:00
|
|
|
#include "src/compiler/raw-machine-assembler.h"
|
2016-06-17 13:19:58 +00:00
|
|
|
#include "src/execution/isolate.h"
|
|
|
|
#include "src/handles/handles.h"
|
|
|
|
|
|
|
|
namespace v8 {
|
|
|
|
namespace internal {
|
|
|
|
namespace compiler {
|
|
|
|
|
2016-11-16 11:48:07 +00:00
|
|
|
class CodeAssemblerTester {
|
2016-06-17 13:19:58 +00:00
|
|
|
public:
|
2020-10-13 15:44:09 +00:00
|
|
|
CodeAssemblerTester(Isolate* isolate,
|
|
|
|
const CallInterfaceDescriptor& descriptor,
|
|
|
|
const char* name = "test")
|
2020-07-23 10:06:02 +00:00
|
|
|
: zone_(isolate->allocator(), ZONE_NAME, kCompressGraphZone),
|
2016-11-16 11:48:07 +00:00
|
|
|
scope_(isolate),
|
Reland "Reland "[deoptimizer] Change deopt entries into builtins""
This is a reland of fbfa9bf4ec72b1b73a96b70ccb68cd98c321511b
The arm64 was missing proper codegen for CFI, thus sizes were off.
Original change's description:
> Reland "[deoptimizer] Change deopt entries into builtins"
>
> This is a reland of 7f58ced72eb65b6b5530ccabaf2eaebe45bf9d33
>
> It fixes the different exit size emitted on x64/Atom CPUs due to
> performance tuning in TurboAssembler::Call. Additionally, add
> cctests to verify the fixed size exits.
>
> Original change's description:
> > [deoptimizer] Change deopt entries into builtins
> >
> > While the overall goal of this commit is to change deoptimization
> > entries into builtins, there are multiple related things happening:
> >
> > - Deoptimization entries, formerly stubs (i.e. Code objects generated
> > at runtime, guaranteed to be immovable), have been converted into
> > builtins. The major restriction is that we now need to preserve the
> > kRootRegister, which was formerly used on most architectures to pass
> > the deoptimization id. The solution differs based on platform.
> > - Renamed DEOPT_ENTRIES_OR_FOR_TESTING code kind to FOR_TESTING.
> > - Removed heap/ support for immovable Code generation.
> > - Removed the DeserializerData class (no longer needed).
> > - arm64: to preserve 4-byte deopt exits, introduced a new optimization
> > in which the final jump to the deoptimization entry is generated
> > once per Code object, and deopt exits can continue to emit a
> > near-call.
> > - arm,ia32,x64: change to fixed-size deopt exits. This reduces exit
> > sizes by 4/8, 5, and 5 bytes, respectively.
> >
> > On arm the deopt exit size is reduced from 12 (or 16) bytes to 8 bytes
> > by using the same strategy as on arm64 (recalc deopt id from return
> > address). Before:
> >
> > e300a002 movw r10, <id>
> > e59fc024 ldr ip, [pc, <entry offset>]
> > e12fff3c blx ip
> >
> > After:
> >
> > e59acb35 ldr ip, [r10, <entry offset>]
> > e12fff3c blx ip
> >
> > On arm64 the deopt exit size remains 4 bytes (or 8 bytes in same cases
> > with CFI). Additionally, up to 4 builtin jumps are emitted per Code
> > object (max 32 bytes added overhead per Code object). Before:
> >
> > 9401cdae bl <entry offset>
> >
> > After:
> >
> > # eager deoptimization entry jump.
> > f95b1f50 ldr x16, [x26, <eager entry offset>]
> > d61f0200 br x16
> > # lazy deoptimization entry jump.
> > f95b2b50 ldr x16, [x26, <lazy entry offset>]
> > d61f0200 br x16
> > # the deopt exit.
> > 97fffffc bl <eager deoptimization entry jump offset>
> >
> > On ia32 the deopt exit size is reduced from 10 to 5 bytes. Before:
> >
> > bb00000000 mov ebx,<id>
> > e825f5372b call <entry>
> >
> > After:
> >
> > e8ea2256ba call <entry>
> >
> > On x64 the deopt exit size is reduced from 12 to 7 bytes. Before:
> >
> > 49c7c511000000 REX.W movq r13,<id>
> > e8ea2f0700 call <entry>
> >
> > After:
> >
> > 41ff9560360000 call [r13+<entry offset>]
> >
> > Bug: v8:8661,v8:8768
> > Change-Id: I13e30aedc360474dc818fecc528ce87c3bfeed42
> > Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2465834
> > Commit-Queue: Jakob Gruber <jgruber@chromium.org>
> > Reviewed-by: Ross McIlroy <rmcilroy@chromium.org>
> > Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
> > Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
> > Cr-Commit-Position: refs/heads/master@{#70597}
>
> Tbr: ulan@chromium.org, tebbi@chromium.org, rmcilroy@chromium.org
> Bug: v8:8661,v8:8768,chromium:1140165
> Change-Id: Ibcd5c39c58a70bf2b2ac221aa375fc68d495e144
> Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2485506
> Reviewed-by: Jakob Gruber <jgruber@chromium.org>
> Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
> Commit-Queue: Jakob Gruber <jgruber@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#70655}
Tbr: ulan@chromium.org, tebbi@chromium.org, rmcilroy@chromium.org
Bug: v8:8661
Bug: v8:8768
Bug: chromium:1140165
Change-Id: I471cc94fc085e527dc9bfb5a84b96bd907c2333f
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2488682
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#70672}
2020-10-21 05:12:25 +00:00
|
|
|
state_(isolate, &zone_, descriptor, CodeKind::FOR_TESTING, name,
|
2021-08-12 11:17:00 +00:00
|
|
|
Builtin::kNoBuiltinId) {}
|
2020-10-13 15:44:09 +00:00
|
|
|
|
|
|
|
// Test generating code for a stub. Assumes VoidDescriptor call interface.
|
|
|
|
explicit CodeAssemblerTester(Isolate* isolate, const char* name = "test")
|
|
|
|
: CodeAssemblerTester(isolate, VoidDescriptor{}, name) {}
|
2016-06-17 13:19:58 +00:00
|
|
|
|
|
|
|
// Test generating code for a JS function (e.g. builtins).
|
2016-11-16 11:48:07 +00:00
|
|
|
CodeAssemblerTester(Isolate* isolate, int parameter_count,
|
2020-08-05 11:48:03 +00:00
|
|
|
CodeKind kind = CodeKind::BUILTIN,
|
2018-04-05 16:25:41 +00:00
|
|
|
const char* name = "test")
|
2020-07-23 10:06:02 +00:00
|
|
|
: zone_(isolate->allocator(), ZONE_NAME, kCompressGraphZone),
|
2016-11-16 11:48:07 +00:00
|
|
|
scope_(isolate),
|
2022-11-17 17:41:41 +00:00
|
|
|
state_(isolate, &zone_, parameter_count, kind, name) {
|
|
|
|
// Parameter count must include at least the receiver.
|
|
|
|
DCHECK_LE(1, parameter_count);
|
|
|
|
}
|
2016-06-17 13:19:58 +00:00
|
|
|
|
2020-08-05 11:48:03 +00:00
|
|
|
CodeAssemblerTester(Isolate* isolate, CodeKind kind,
|
2018-04-05 16:25:41 +00:00
|
|
|
const char* name = "test")
|
2022-11-17 17:41:41 +00:00
|
|
|
: CodeAssemblerTester(isolate, 1, kind, name) {}
|
2016-11-16 11:48:07 +00:00
|
|
|
|
2017-12-18 18:55:23 +00:00
|
|
|
CodeAssemblerTester(Isolate* isolate, CallDescriptor* call_descriptor,
|
|
|
|
const char* name = "test")
|
2020-07-23 10:06:02 +00:00
|
|
|
: zone_(isolate->allocator(), ZONE_NAME, kCompressGraphZone),
|
2017-10-11 10:22:40 +00:00
|
|
|
scope_(isolate),
|
Reland "Reland "[deoptimizer] Change deopt entries into builtins""
This is a reland of fbfa9bf4ec72b1b73a96b70ccb68cd98c321511b
The arm64 was missing proper codegen for CFI, thus sizes were off.
Original change's description:
> Reland "[deoptimizer] Change deopt entries into builtins"
>
> This is a reland of 7f58ced72eb65b6b5530ccabaf2eaebe45bf9d33
>
> It fixes the different exit size emitted on x64/Atom CPUs due to
> performance tuning in TurboAssembler::Call. Additionally, add
> cctests to verify the fixed size exits.
>
> Original change's description:
> > [deoptimizer] Change deopt entries into builtins
> >
> > While the overall goal of this commit is to change deoptimization
> > entries into builtins, there are multiple related things happening:
> >
> > - Deoptimization entries, formerly stubs (i.e. Code objects generated
> > at runtime, guaranteed to be immovable), have been converted into
> > builtins. The major restriction is that we now need to preserve the
> > kRootRegister, which was formerly used on most architectures to pass
> > the deoptimization id. The solution differs based on platform.
> > - Renamed DEOPT_ENTRIES_OR_FOR_TESTING code kind to FOR_TESTING.
> > - Removed heap/ support for immovable Code generation.
> > - Removed the DeserializerData class (no longer needed).
> > - arm64: to preserve 4-byte deopt exits, introduced a new optimization
> > in which the final jump to the deoptimization entry is generated
> > once per Code object, and deopt exits can continue to emit a
> > near-call.
> > - arm,ia32,x64: change to fixed-size deopt exits. This reduces exit
> > sizes by 4/8, 5, and 5 bytes, respectively.
> >
> > On arm the deopt exit size is reduced from 12 (or 16) bytes to 8 bytes
> > by using the same strategy as on arm64 (recalc deopt id from return
> > address). Before:
> >
> > e300a002 movw r10, <id>
> > e59fc024 ldr ip, [pc, <entry offset>]
> > e12fff3c blx ip
> >
> > After:
> >
> > e59acb35 ldr ip, [r10, <entry offset>]
> > e12fff3c blx ip
> >
> > On arm64 the deopt exit size remains 4 bytes (or 8 bytes in same cases
> > with CFI). Additionally, up to 4 builtin jumps are emitted per Code
> > object (max 32 bytes added overhead per Code object). Before:
> >
> > 9401cdae bl <entry offset>
> >
> > After:
> >
> > # eager deoptimization entry jump.
> > f95b1f50 ldr x16, [x26, <eager entry offset>]
> > d61f0200 br x16
> > # lazy deoptimization entry jump.
> > f95b2b50 ldr x16, [x26, <lazy entry offset>]
> > d61f0200 br x16
> > # the deopt exit.
> > 97fffffc bl <eager deoptimization entry jump offset>
> >
> > On ia32 the deopt exit size is reduced from 10 to 5 bytes. Before:
> >
> > bb00000000 mov ebx,<id>
> > e825f5372b call <entry>
> >
> > After:
> >
> > e8ea2256ba call <entry>
> >
> > On x64 the deopt exit size is reduced from 12 to 7 bytes. Before:
> >
> > 49c7c511000000 REX.W movq r13,<id>
> > e8ea2f0700 call <entry>
> >
> > After:
> >
> > 41ff9560360000 call [r13+<entry offset>]
> >
> > Bug: v8:8661,v8:8768
> > Change-Id: I13e30aedc360474dc818fecc528ce87c3bfeed42
> > Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2465834
> > Commit-Queue: Jakob Gruber <jgruber@chromium.org>
> > Reviewed-by: Ross McIlroy <rmcilroy@chromium.org>
> > Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
> > Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
> > Cr-Commit-Position: refs/heads/master@{#70597}
>
> Tbr: ulan@chromium.org, tebbi@chromium.org, rmcilroy@chromium.org
> Bug: v8:8661,v8:8768,chromium:1140165
> Change-Id: Ibcd5c39c58a70bf2b2ac221aa375fc68d495e144
> Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2485506
> Reviewed-by: Jakob Gruber <jgruber@chromium.org>
> Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
> Commit-Queue: Jakob Gruber <jgruber@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#70655}
Tbr: ulan@chromium.org, tebbi@chromium.org, rmcilroy@chromium.org
Bug: v8:8661
Bug: v8:8768
Bug: chromium:1140165
Change-Id: I471cc94fc085e527dc9bfb5a84b96bd907c2333f
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2488682
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#70672}
2020-10-21 05:12:25 +00:00
|
|
|
state_(isolate, &zone_, call_descriptor, CodeKind::FOR_TESTING, name,
|
2021-08-12 11:17:00 +00:00
|
|
|
Builtin::kNoBuiltinId) {}
|
2017-10-11 10:22:40 +00:00
|
|
|
|
2016-11-16 11:48:07 +00:00
|
|
|
CodeAssemblerState* state() { return &state_; }
|
|
|
|
|
2017-10-11 10:22:40 +00:00
|
|
|
// Direct low-level access to the machine assembler, for testing only.
|
|
|
|
RawMachineAssembler* raw_assembler_for_testing() {
|
|
|
|
return state_.raw_assembler_.get();
|
|
|
|
}
|
|
|
|
|
2018-07-06 08:58:43 +00:00
|
|
|
Handle<Code> GenerateCode() {
|
2018-11-13 16:28:21 +00:00
|
|
|
return GenerateCode(AssemblerOptions::Default(scope_.isolate()));
|
2018-07-06 08:58:43 +00:00
|
|
|
}
|
2016-06-17 13:19:58 +00:00
|
|
|
|
2018-08-02 11:16:52 +00:00
|
|
|
Handle<Code> GenerateCode(const AssemblerOptions& options) {
|
2018-11-13 16:28:21 +00:00
|
|
|
if (state_.InsideBlock()) {
|
|
|
|
CodeAssembler(&state_).Unreachable();
|
|
|
|
}
|
Profile-guided optimization of builtins
Design doc:
https://docs.google.com/document/d/1szInbXZfaErWW70d30hJsOLL0Es-l5_g8d2rXm1ZBqI/edit?usp=sharing
V8 can already collect data about how many times each basic block in the
builtins is run. This change enables using that data for profile-guided
optimization. New comments in BUILD.gn describe how to use this feature.
A few implementation details worth mentioning, which aren't covered in
the design doc:
- BasicBlockProfilerData currently contains an array of RPO numbers.
However, this array is always just [0, 1, 2, 3, ...], so this change
removes that array. A new DCHECK in BasicBlockInstrumentor::Instrument
ensures that the removal is valid.
- RPO numbers, while useful for printing data that matches with the
stringified schedule, are not useful for matching profiling data with
blocks that haven't been scheduled yet. This change adds a new array
of block IDs in BasicBlockProfilerData, so that block counters can be
used for PGO.
- Basic block counters need to be written to a file so that they can be
provided to a subsequent run of mksnapshot, but the design doc doesn't
specify the transfer format or what file is used. In this change, I
propose using the existing v8.log file for that purpose. Block count
records look like this:
block,TestLessThanHandler,37,29405
This line indicates that block ID 37 in TestLessThanHandler was run
29405 times. If multiple lines refer to the same block, the reader
adds them all together. I like this format because it's easy to use:
- V8 already has robust logic for creating the log file, naming it to
avoid conflicts in multi-process situations, etc.
- Line order doesn't matter, and interleaved writes from various
logging sources are fine, given that V8 writes each line atomically.
- Combining multiple sources of profiling data is as simple as
concatenating their v8.log files together.
- It is a good idea to avoid making any changes based on profiling data
if the function being compiled doesn't match the one that was
profiled, since it is common to use profiling data downloaded from a
central lab which is updated only periodically. To check whether a
function matches, I propose using a hash of the Graph state right
before scheduling. This might be stricter than necessary, as some
changes to the function might be small enough that the profile data is
still relevant, but I'd rather err on the side of not making incorrect
changes. This hash is also written to the v8.log file, in a line that
looks like this:
builtin_hash,LdaZeroHandler,3387822046
Bug: v8:10470
Change-Id: I429e5ce5efa94e01e7489deb3996012cf860cf13
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2220765
Commit-Queue: Seth Brenith <seth.brenith@microsoft.com>
Reviewed-by: Ross McIlroy <rmcilroy@chromium.org>
Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#69008}
2020-07-16 16:37:08 +00:00
|
|
|
return CodeAssembler::GenerateCode(&state_, options, nullptr);
|
2018-08-02 11:16:52 +00:00
|
|
|
}
|
|
|
|
|
2016-06-17 13:19:58 +00:00
|
|
|
Handle<Code> GenerateCodeCloseAndEscape() {
|
2016-12-13 13:55:03 +00:00
|
|
|
return scope_.CloseAndEscape(GenerateCode());
|
2016-06-17 13:19:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2016-11-16 11:48:07 +00:00
|
|
|
Zone zone_;
|
2016-06-17 13:19:58 +00:00
|
|
|
HandleScope scope_;
|
2016-11-16 11:48:07 +00:00
|
|
|
CodeAssemblerState state_;
|
2016-06-17 13:19:58 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace compiler
|
|
|
|
} // namespace internal
|
|
|
|
} // namespace v8
|
2017-09-21 02:04:27 +00:00
|
|
|
|
2022-09-01 14:11:31 +00:00
|
|
|
#endif // V8_TEST_COMMON_CODE_ASSEMBLER_TESTER_H_
|