Commit b5c542ba authored by adamk's avatar adamk Committed by Commit bot

Avoid static initializers in PropertyAccessCompiler

Introduce AccessCompilerData which hangs off the Isolate, and initialize
it when the first PropertyAccessCompiler is instantiated. This avoids
TSAN failures when trying to access load/store calling convention arrays.

BUG=v8:5427

Review-Url: https://codereview.chromium.org/2389313002
Cr-Commit-Position: refs/heads/master@{#40055}
parent 4b575dfc
......@@ -1378,6 +1378,7 @@ v8_source_set("v8_base") {
"src/heap/store-buffer.h",
"src/i18n.cc",
"src/i18n.h",
"src/ic/access-compiler-data.h",
"src/ic/access-compiler.cc",
"src/ic/access-compiler.h",
"src/ic/call-optimization.cc",
......
// Copyright 2016 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.
#ifndef V8_IC_ACCESS_COMPILER_DATA_H_
#define V8_IC_ACCESS_COMPILER_DATA_H_
#include <memory>
#include "src/allocation.h"
#include "src/base/macros.h"
namespace v8 {
namespace internal {
class AccessCompilerData {
public:
AccessCompilerData() {}
bool IsInitialized() const { return load_calling_convention_ != nullptr; }
void Initialize(int load_register_count, const Register* load_registers,
int store_register_count, const Register* store_registers) {
load_calling_convention_.reset(NewArray<Register>(load_register_count));
for (int i = 0; i < load_register_count; ++i) {
load_calling_convention_[i] = load_registers[i];
}
store_calling_convention_.reset(NewArray<Register>(store_register_count));
for (int i = 0; i < store_register_count; ++i) {
store_calling_convention_[i] = store_registers[i];
}
}
Register* load_calling_convention() { return load_calling_convention_.get(); }
Register* store_calling_convention() {
return store_calling_convention_.get();
}
private:
std::unique_ptr<Register[]> load_calling_convention_;
std::unique_ptr<Register[]> store_calling_convention_;
DISALLOW_COPY_AND_ASSIGN(AccessCompilerData);
};
} // namespace internal
} // namespace v8
#endif // V8_IC_ACCESS_COMPILER_DATA_H_
......@@ -4,7 +4,6 @@
#include "src/ic/access-compiler.h"
namespace v8 {
namespace internal {
......@@ -42,13 +41,17 @@ void PropertyAccessCompiler::TailCallBuiltin(MacroAssembler* masm,
GenerateTailCall(masm, code);
}
Register* PropertyAccessCompiler::GetCallingConvention(Code::Kind kind) {
Register* PropertyAccessCompiler::GetCallingConvention(Isolate* isolate,
Code::Kind kind) {
AccessCompilerData* data = isolate->access_compiler_data();
if (!data->IsInitialized()) {
InitializePlatformSpecific(data);
}
if (kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC) {
return load_calling_convention();
return data->load_calling_convention();
}
DCHECK(kind == Code::STORE_IC || kind == Code::KEYED_STORE_IC);
return store_calling_convention();
return data->store_calling_convention();
}
......
......@@ -6,13 +6,13 @@
#define V8_IC_ACCESS_COMPILER_H_
#include "src/code-stubs.h"
#include "src/ic/access-compiler-data.h"
#include "src/macro-assembler.h"
#include "src/objects.h"
namespace v8 {
namespace internal {
class PropertyAccessCompiler BASE_EMBEDDED {
public:
static Builtins::Name MissBuiltin(Code::Kind kind) {
......@@ -36,7 +36,7 @@ class PropertyAccessCompiler BASE_EMBEDDED {
protected:
PropertyAccessCompiler(Isolate* isolate, Code::Kind kind,
CacheHolderFlag cache_holder)
: registers_(GetCallingConvention(kind)),
: registers_(GetCallingConvention(isolate, kind)),
kind_(kind),
cache_holder_(cache_holder),
isolate_(isolate),
......@@ -59,11 +59,6 @@ class PropertyAccessCompiler BASE_EMBEDDED {
Register scratch1() const { return registers_[2]; }
Register scratch2() const { return registers_[3]; }
static Register* GetCallingConvention(Code::Kind);
static Register* load_calling_convention();
static Register* store_calling_convention();
static Register* keyed_store_calling_convention();
Register* registers_;
static void GenerateTailCall(MacroAssembler* masm, Handle<Code> code);
......@@ -72,6 +67,9 @@ class PropertyAccessCompiler BASE_EMBEDDED {
Handle<Code> GetCodeWithFlags(Code::Flags flags, Handle<Name> name);
private:
static Register* GetCallingConvention(Isolate* isolate, Code::Kind kind);
static void InitializePlatformSpecific(AccessCompilerData* data);
Code::Kind kind_;
CacheHolderFlag cache_holder_;
......
......@@ -17,24 +17,22 @@ void PropertyAccessCompiler::GenerateTailCall(MacroAssembler* masm,
__ Jump(code, RelocInfo::CODE_TARGET);
}
Register* PropertyAccessCompiler::load_calling_convention() {
// receiver, name, scratch1, scratch2, scratch3.
void PropertyAccessCompiler::InitializePlatformSpecific(
AccessCompilerData* data) {
Register receiver = LoadDescriptor::ReceiverRegister();
Register name = LoadDescriptor::NameRegister();
static Register registers[] = {receiver, name, r3, r0, r4};
return registers;
}
// Load calling convention.
// receiver, name, scratch1, scratch2, scratch3.
Register load_registers[] = {receiver, name, r3, r0, r4};
Register* PropertyAccessCompiler::store_calling_convention() {
// Store calling convention.
// receiver, name, scratch1, scratch2.
Register receiver = StoreDescriptor::ReceiverRegister();
Register name = StoreDescriptor::NameRegister();
static Register registers[] = {receiver, name, r3, r4};
return registers;
}
Register store_registers[] = {receiver, name, r3, r4};
data->Initialize(arraysize(load_registers), load_registers,
arraysize(store_registers), store_registers);
}
#undef __
} // namespace internal
......
......@@ -25,23 +25,22 @@ void PropertyAccessCompiler::GenerateTailCall(MacroAssembler* masm,
// registers are actually scratch registers, and which are important. For now,
// we use the same assignments as ARM to remain on the safe side.
Register* PropertyAccessCompiler::load_calling_convention() {
// receiver, name, scratch1, scratch2, scratch3.
void PropertyAccessCompiler::InitializePlatformSpecific(
AccessCompilerData* data) {
Register receiver = LoadDescriptor::ReceiverRegister();
Register name = LoadDescriptor::NameRegister();
static Register registers[] = {receiver, name, x3, x0, x4};
return registers;
}
// Load calling convention.
// receiver, name, scratch1, scratch2, scratch3.
Register load_registers[] = {receiver, name, x3, x0, x4};
Register* PropertyAccessCompiler::store_calling_convention() {
// receiver, value, scratch1, scratch2.
Register receiver = StoreDescriptor::ReceiverRegister();
Register name = StoreDescriptor::NameRegister();
static Register registers[] = {receiver, name, x3, x4};
return registers;
}
// Store calling convention.
// receiver, name, scratch1, scratch2.
Register store_registers[] = {receiver, name, x3, x4};
data->Initialize(arraysize(load_registers), load_registers,
arraysize(store_registers), store_registers);
}
#undef __
} // namespace internal
......
......@@ -16,22 +16,21 @@ void PropertyAccessCompiler::GenerateTailCall(MacroAssembler* masm,
__ jmp(code, RelocInfo::CODE_TARGET);
}
Register* PropertyAccessCompiler::load_calling_convention() {
// receiver, name, scratch1, scratch2, scratch3.
void PropertyAccessCompiler::InitializePlatformSpecific(
AccessCompilerData* data) {
Register receiver = LoadDescriptor::ReceiverRegister();
Register name = LoadDescriptor::NameRegister();
static Register registers[] = {receiver, name, ebx, eax, edi};
return registers;
}
// Load calling convention.
// receiver, name, scratch1, scratch2, scratch3.
Register load_registers[] = {receiver, name, ebx, eax, edi};
Register* PropertyAccessCompiler::store_calling_convention() {
// Store calling convention.
// receiver, name, scratch1, scratch2.
Register receiver = StoreDescriptor::ReceiverRegister();
Register name = StoreDescriptor::NameRegister();
static Register registers[] = {receiver, name, ebx, edi};
return registers;
Register store_registers[] = {receiver, name, ebx, edi};
data->Initialize(arraysize(load_registers), load_registers,
arraysize(store_registers), store_registers);
}
#undef __
......
......@@ -17,24 +17,22 @@ void PropertyAccessCompiler::GenerateTailCall(MacroAssembler* masm,
__ Jump(code, RelocInfo::CODE_TARGET);
}
Register* PropertyAccessCompiler::load_calling_convention() {
// receiver, name, scratch1, scratch2, scratch3.
void PropertyAccessCompiler::InitializePlatformSpecific(
AccessCompilerData* data) {
Register receiver = LoadDescriptor::ReceiverRegister();
Register name = LoadDescriptor::NameRegister();
static Register registers[] = {receiver, name, a3, a0, t0};
return registers;
}
// Load calling convention.
// receiver, name, scratch1, scratch2, scratch3.
Register load_registers[] = {receiver, name, a3, a0, t0};
Register* PropertyAccessCompiler::store_calling_convention() {
// Store calling convention.
// receiver, name, scratch1, scratch2.
Register receiver = StoreDescriptor::ReceiverRegister();
Register name = StoreDescriptor::NameRegister();
static Register registers[] = {receiver, name, a3, t0};
return registers;
}
Register store_registers[] = {receiver, name, a3, t0};
data->Initialize(arraysize(load_registers), load_registers,
arraysize(store_registers), store_registers);
}
#undef __
} // namespace internal
......
......@@ -17,24 +17,22 @@ void PropertyAccessCompiler::GenerateTailCall(MacroAssembler* masm,
__ Jump(code, RelocInfo::CODE_TARGET);
}
Register* PropertyAccessCompiler::load_calling_convention() {
// receiver, name, scratch1, scratch2, scratch3.
void PropertyAccessCompiler::InitializePlatformSpecific(
AccessCompilerData* data) {
Register receiver = LoadDescriptor::ReceiverRegister();
Register name = LoadDescriptor::NameRegister();
static Register registers[] = {receiver, name, a3, a0, a4};
return registers;
}
// Load calling convention.
// receiver, name, scratch1, scratch2, scratch3.
Register load_registers[] = {receiver, name, a3, a0, a4};
Register* PropertyAccessCompiler::store_calling_convention() {
// Store calling convention.
// receiver, name, scratch1, scratch2.
Register receiver = StoreDescriptor::ReceiverRegister();
Register name = StoreDescriptor::NameRegister();
static Register registers[] = {receiver, name, a3, a4};
return registers;
}
Register store_registers[] = {receiver, name, a3, a4};
data->Initialize(arraysize(load_registers), load_registers,
arraysize(store_registers), store_registers);
}
#undef __
} // namespace internal
......
......@@ -17,24 +17,22 @@ void PropertyAccessCompiler::GenerateTailCall(MacroAssembler* masm,
__ Jump(code, RelocInfo::CODE_TARGET);
}
Register* PropertyAccessCompiler::load_calling_convention() {
// receiver, name, scratch1, scratch2, scratch3.
void PropertyAccessCompiler::InitializePlatformSpecific(
AccessCompilerData* data) {
Register receiver = LoadDescriptor::ReceiverRegister();
Register name = LoadDescriptor::NameRegister();
static Register registers[] = {receiver, name, r6, r3, r7};
return registers;
}
// Load calling convention.
// receiver, name, scratch1, scratch2, scratch3.
Register load_registers[] = {receiver, name, r6, r3, r7};
Register* PropertyAccessCompiler::store_calling_convention() {
// Store calling convention.
// receiver, name, scratch1, scratch2.
Register receiver = StoreDescriptor::ReceiverRegister();
Register name = StoreDescriptor::NameRegister();
static Register registers[] = {receiver, name, r6, r7};
return registers;
}
Register store_registers[] = {receiver, name, r6, r7};
data->Initialize(arraysize(load_registers), load_registers,
arraysize(store_registers), store_registers);
}
#undef __
} // namespace internal
......
......@@ -18,20 +18,21 @@ void PropertyAccessCompiler::GenerateTailCall(MacroAssembler* masm,
__ Jump(code, RelocInfo::CODE_TARGET);
}
Register* PropertyAccessCompiler::load_calling_convention() {
// receiver, name, scratch1, scratch2, scratch3.
void PropertyAccessCompiler::InitializePlatformSpecific(
AccessCompilerData* data) {
Register receiver = LoadDescriptor::ReceiverRegister();
Register name = LoadDescriptor::NameRegister();
static Register registers[] = {receiver, name, r5, r2, r6};
return registers;
}
Register* PropertyAccessCompiler::store_calling_convention() {
// Load calling convention.
// receiver, name, scratch1, scratch2, scratch3.
Register load_registers[] = {receiver, name, r5, r2, r6};
// Store calling convention.
// receiver, name, scratch1, scratch2.
Register receiver = StoreDescriptor::ReceiverRegister();
Register name = StoreDescriptor::NameRegister();
static Register registers[] = {receiver, name, r5, r6};
return registers;
Register store_registers[] = {receiver, name, r5, r6};
data->Initialize(arraysize(load_registers), load_registers,
arraysize(store_registers), store_registers);
}
#undef __
......
......@@ -11,30 +11,27 @@ namespace internal {
#define __ ACCESS_MASM(masm)
void PropertyAccessCompiler::GenerateTailCall(MacroAssembler* masm,
Handle<Code> code) {
__ jmp(code, RelocInfo::CODE_TARGET);
}
Register* PropertyAccessCompiler::load_calling_convention() {
// receiver, name, scratch1, scratch2, scratch3.
void PropertyAccessCompiler::InitializePlatformSpecific(
AccessCompilerData* data) {
Register receiver = LoadDescriptor::ReceiverRegister();
Register name = LoadDescriptor::NameRegister();
static Register registers[] = {receiver, name, rax, rbx, rdi};
return registers;
}
// Load calling convention.
// receiver, name, scratch1, scratch2, scratch3.
Register load_registers[] = {receiver, name, rax, rbx, rdi};
Register* PropertyAccessCompiler::store_calling_convention() {
// Store calling convention.
// receiver, name, scratch1, scratch2.
Register receiver = StoreDescriptor::ReceiverRegister();
Register name = StoreDescriptor::NameRegister();
static Register registers[] = {receiver, name, rbx, rdi};
return registers;
}
Register store_registers[] = {receiver, name, rbx, rdi};
data->Initialize(arraysize(load_registers), load_registers,
arraysize(store_registers), store_registers);
}
#undef __
} // namespace internal
......
......@@ -16,22 +16,21 @@ void PropertyAccessCompiler::GenerateTailCall(MacroAssembler* masm,
__ jmp(code, RelocInfo::CODE_TARGET);
}
Register* PropertyAccessCompiler::load_calling_convention() {
// receiver, name, scratch1, scratch2, scratch3.
void PropertyAccessCompiler::InitializePlatformSpecific(
AccessCompilerData* data) {
Register receiver = LoadDescriptor::ReceiverRegister();
Register name = LoadDescriptor::NameRegister();
static Register registers[] = {receiver, name, ebx, eax, edi};
return registers;
}
// Load calling convention.
// receiver, name, scratch1, scratch2, scratch3.
Register load_registers[] = {receiver, name, ebx, eax, edi};
Register* PropertyAccessCompiler::store_calling_convention() {
// Store calling convention.
// receiver, name, scratch1, scratch2.
Register receiver = StoreDescriptor::ReceiverRegister();
Register name = StoreDescriptor::NameRegister();
static Register registers[] = {receiver, name, ebx, edi};
return registers;
Register store_registers[] = {receiver, name, ebx, edi};
data->Initialize(arraysize(load_registers), load_registers,
arraysize(store_registers), store_registers);
}
#undef __
......
......@@ -26,6 +26,7 @@
#include "src/deoptimizer.h"
#include "src/external-reference-table.h"
#include "src/frames-inl.h"
#include "src/ic/access-compiler-data.h"
#include "src/ic/stub-cache.h"
#include "src/interface-descriptors.h"
#include "src/interpreter/interpreter.h"
......@@ -2211,6 +2212,9 @@ Isolate::~Isolate() {
delete[] call_descriptor_data_;
call_descriptor_data_ = NULL;
delete access_compiler_data_;
access_compiler_data_ = NULL;
delete regexp_stack_;
regexp_stack_ = NULL;
......@@ -2378,6 +2382,7 @@ bool Isolate::Init(Deserializer* des) {
date_cache_ = new DateCache();
call_descriptor_data_ =
new CallInterfaceDescriptorData[CallDescriptors::NUMBER_OF_DESCRIPTORS];
access_compiler_data_ = new AccessCompilerData();
cpu_profiler_ = new CpuProfiler(this);
heap_profiler_ = new HeapProfiler(heap());
interpreter_ = new interpreter::Interpreter(this);
......
......@@ -33,6 +33,7 @@ class RandomNumberGenerator;
namespace internal {
class AccessCompilerData;
class BasicBlockProfiler;
class Bootstrapper;
class CancelableTaskManager;
......@@ -1029,6 +1030,8 @@ class Isolate {
CallInterfaceDescriptorData* call_descriptor_data(int index);
AccessCompilerData* access_compiler_data() { return access_compiler_data_; }
void IterateDeferredHandles(ObjectVisitor* visitor);
void LinkDeferredHandles(DeferredHandles* deferred_handles);
void UnlinkDeferredHandles(DeferredHandles* deferred_handles);
......@@ -1342,6 +1345,7 @@ class Isolate {
List<int> regexp_indices_;
DateCache* date_cache_;
CallInterfaceDescriptorData* call_descriptor_data_;
AccessCompilerData* access_compiler_data_;
base::RandomNumberGenerator* random_number_generator_;
base::AtomicValue<RAILMode> rail_mode_;
......
......@@ -950,6 +950,7 @@
'i18n.h',
'icu_util.cc',
'icu_util.h',
'ic/access-compiler-data.h',
'ic/access-compiler.cc',
'ic/access-compiler.h',
'ic/call-optimization.cc',
......
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