Commit 3a89fc8e authored by Igor Sheludko's avatar Igor Sheludko Committed by Commit Bot

[zone] Final cleanup of zone allocations

... by migrating old-style code
  MyObject* obj = new (zone) MyObject(...)

to the new style
  MyObject* obj = zone->New<MyObject>(...)

... and prohibiting accidental use of the old-style.

Bug: v8:10689
Change-Id: Id75774ac12e3d0f95cb3a538066dffbf7815e438
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2300490
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Reviewed-by: 's avatarGeorg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#68905}
parent eaaf0c2c
......@@ -1116,7 +1116,7 @@ const Operator* JSOperatorBuilder::LoadModule(int32_t cell_index) {
}
const Operator* JSOperatorBuilder::GetImportMeta() {
return new (zone()) Operator( // --
return zone()->New<Operator>( // --
IrOpcode::kJSGetImportMeta, // opcode
Operator::kNoProperties, // flags
"JSGetImportMeta", // name
......
......@@ -1743,7 +1743,7 @@ const Operator* SimplifiedOperatorBuilder::NewSmiOrObjectElements(
const Operator* SimplifiedOperatorBuilder::NewArgumentsElements(
CreateArgumentsType type, int formal_parameter_count) {
return new (zone()) Operator1<NewArgumentsElementsParameters>( // --
return zone()->New<Operator1<NewArgumentsElementsParameters>>( // --
IrOpcode::kNewArgumentsElements, // opcode
Operator::kEliminatable, // flags
"NewArgumentsElements", // name
......@@ -1920,7 +1920,7 @@ const Operator* SimplifiedOperatorBuilder::FastApiCall(
FastApiCallNode::kFastTargetInputCount) + // fast call
static_cast<int>(descriptor->ParameterCount()) + // slow call
FastApiCallNode::kEffectAndControlInputCount;
return new (zone_) Operator1<FastApiCallParameters>(
return zone()->New<Operator1<FastApiCallParameters>>(
IrOpcode::kFastApiCall, Operator::kNoThrow, "FastApiCall",
value_input_count, 1, 1, 1, 1, 0,
FastApiCallParameters(signature, feedback, descriptor));
......
......@@ -39,9 +39,6 @@ class V8_EXPORT_PRIVATE Zone final {
Zone(AccountingAllocator* allocator, const char* name);
~Zone();
// TODO(v8:10689): Remove once all allocation sites are migrated.
void* New(size_t size) { return Allocate<void>(size); }
// Allocate 'size' bytes of uninitialized memory in the Zone; expands the Zone
// by allocating new segments of memory on demand using AccountingAllocator
// (see AccountingAllocator::AllocateSegment()).
......@@ -178,10 +175,16 @@ class V8_EXPORT_PRIVATE Zone final {
// allocated in the Zone. Use it as a base class; see ast.h.
class ZoneObject {
public:
// Allocate a new ZoneObject of 'size' bytes in the Zone.
void* operator new(size_t size, Zone* zone) { return zone->New(size); }
// The accidential old-style pattern
// new (zone) SomeObject(...)
// now produces compilation error. The proper way of allocating objects in
// Zones looks like this:
// zone->New<SomeObject>(...)
void* operator new(size_t, Zone*) = delete; // See explanation above.
// Allow non-allocating placement new.
void* operator new(size_t size, void* ptr) { return ptr; }
void* operator new(size_t size, void* ptr) { // See explanation above.
return ptr;
}
// Ideally, the delete operator should be private instead of
// public, but unfortunately the compiler sometimes synthesizes
......@@ -191,8 +194,9 @@ class ZoneObject {
// ZoneObjects should never be deleted individually; use
// Zone::DeleteAll() to delete all zone objects in one go.
// Note, that descructors will not be called.
void operator delete(void*, size_t) { UNREACHABLE(); }
void operator delete(void* pointer, Zone* zone) { UNREACHABLE(); }
void operator delete(void* pointer, Zone* zone) = delete;
};
// The ZoneAllocationPolicy is used to specialize generic data
......@@ -221,17 +225,12 @@ class ZoneAllocationPolicy {
} // namespace internal
} // namespace v8
// The accidential pattern
// new (zone) SomeObject()
// where SomeObject does not inherit from ZoneObject leads to nasty crashes.
// This triggers a compile-time error instead.
template <class T, typename = typename std::enable_if<std::is_convertible<
T, const v8::internal::Zone*>::value>::type>
void* operator new(size_t size, T zone) {
static_assert(false && sizeof(T),
"Placement new with a zone is only permitted for classes "
"inheriting from ZoneObject");
UNREACHABLE();
}
// The accidential old-style pattern
// new (zone) SomeObject(...)
// now produces compilation error. The proper way of allocating objects in
// Zones looks like this:
// zone->New<SomeObject>(...)
void* operator new(size_t, v8::internal::Zone*) = delete; // See explanation.
void operator delete(void*, v8::internal::Zone*) = delete; // See explanation.
#endif // V8_ZONE_ZONE_H_
......@@ -498,10 +498,13 @@ Handle<Code> WasmFunctionWrapper::GetWrapperCode() {
return code;
}
// This struct is just a type tag for Zone::NewArray<T>(size_t) call.
struct WasmFunctionCompilerBuffer {};
void WasmFunctionCompiler::Build(const byte* start, const byte* end) {
size_t locals_size = local_decls.Size();
size_t total_size = end - start + locals_size + 1;
byte* buffer = zone()->NewArray<byte>(total_size);
byte* buffer = zone()->NewArray<byte, WasmFunctionCompilerBuffer>(total_size);
// Prepend the local decls to the code.
local_decls.Emit(buffer);
// Emit the code.
......
......@@ -10,12 +10,15 @@
namespace v8 {
namespace internal {
// This struct is just a type tag for Zone::Allocate<T>(size_t) call.
struct ZoneTest {};
TEST(Zone, 8ByteAlignment) {
AccountingAllocator allocator;
Zone zone(&allocator, ZONE_NAME);
for (size_t i = 0; i < 16; ++i) {
ASSERT_EQ(reinterpret_cast<intptr_t>(zone.New(i)) % 8, 0);
ASSERT_EQ(reinterpret_cast<intptr_t>(zone.Allocate<ZoneTest>(i)) % 8, 0);
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment