Commit 282cdf28 authored by ahaas's avatar ahaas Committed by Commit bot

[wasm] Use a LazyInstance in wasm-linkage.cc to avoid a data race.

The initialization of static variables that were used originally caused
a data race because multiple threads tried to initialize the variables
at the same time. The use of a LazyInstance guarantees that the
variables get initialized exactly once.

The same problem also existed in c-linkage.cc. There I fixed the problem
by using a local variable instead of a static variable.

BUG=v8:5242
R=titzer@chromium.org

Review-Url: https://codereview.chromium.org/2202433003
Cr-Commit-Position: refs/heads/master@{#38221}
parent 9005b584
...@@ -191,12 +191,11 @@ CallDescriptor* Linkage::GetSimplifiedCDescriptor( ...@@ -191,12 +191,11 @@ CallDescriptor* Linkage::GetSimplifiedCDescriptor(
const int parameter_count = static_cast<int>(msig->parameter_count()); const int parameter_count = static_cast<int>(msig->parameter_count());
#ifdef PARAM_REGISTERS #ifdef PARAM_REGISTERS
static const Register kParamRegisters[] = {PARAM_REGISTERS}; const Register kParamRegisters[] = {PARAM_REGISTERS};
static const int kParamRegisterCount = const int kParamRegisterCount = static_cast<int>(arraysize(kParamRegisters));
static_cast<int>(arraysize(kParamRegisters));
#else #else
static const Register* kParamRegisters = nullptr; const Register* kParamRegisters = nullptr;
static const int kParamRegisterCount = 0; const int kParamRegisterCount = 0;
#endif #endif
#ifdef STACK_SHADOW_WORDS #ifdef STACK_SHADOW_WORDS
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
// found in the LICENSE file. // found in the LICENSE file.
#include "src/assembler.h" #include "src/assembler.h"
#include "src/base/lazy-instance.h"
#include "src/macro-assembler.h" #include "src/macro-assembler.h"
#include "src/register-configuration.h" #include "src/register-configuration.h"
...@@ -206,55 +207,61 @@ struct Allocator { ...@@ -206,55 +207,61 @@ struct Allocator {
}; };
} // namespace } // namespace
static Allocator GetReturnRegisters() { struct ParameterRegistersCreateTrait {
#ifdef GP_RETURN_REGISTERS static void Construct(Allocator* allocated_ptr) {
static const Register kGPReturnRegisters[] = {GP_RETURN_REGISTERS}; #ifdef GP_PARAM_REGISTERS
static const int kGPReturnRegistersCount = static const Register kGPParamRegisters[] = {GP_PARAM_REGISTERS};
static_cast<int>(arraysize(kGPReturnRegisters)); static const int kGPParamRegistersCount =
static_cast<int>(arraysize(kGPParamRegisters));
#else #else
static const Register* kGPReturnRegisters = nullptr; static const Register* kGPParamRegisters = nullptr;
static const int kGPReturnRegistersCount = 0; static const int kGPParamRegistersCount = 0;
#endif #endif
#ifdef FP_RETURN_REGISTERS #ifdef FP_PARAM_REGISTERS
static const DoubleRegister kFPReturnRegisters[] = {FP_RETURN_REGISTERS}; static const DoubleRegister kFPParamRegisters[] = {FP_PARAM_REGISTERS};
static const int kFPReturnRegistersCount = static const int kFPParamRegistersCount =
static_cast<int>(arraysize(kFPReturnRegisters)); static_cast<int>(arraysize(kFPParamRegisters));
#else #else
static const DoubleRegister* kFPReturnRegisters = nullptr; static const DoubleRegister* kFPParamRegisters = nullptr;
static const int kFPReturnRegistersCount = 0; static const int kFPParamRegistersCount = 0;
#endif #endif
Allocator rets(kGPReturnRegisters, kGPReturnRegistersCount, new (allocated_ptr) Allocator(kGPParamRegisters, kGPParamRegistersCount,
kFPReturnRegisters, kFPReturnRegistersCount); kFPParamRegisters, kFPParamRegistersCount);
}
};
return rets; static base::LazyInstance<Allocator, ParameterRegistersCreateTrait>::type
} parameter_registers = LAZY_INSTANCE_INITIALIZER;
static Allocator GetParameterRegisters() { struct ReturnRegistersCreateTrait {
#ifdef GP_PARAM_REGISTERS static void Construct(Allocator* allocated_ptr) {
static const Register kGPParamRegisters[] = {GP_PARAM_REGISTERS}; #ifdef GP_RETURN_REGISTERS
static const int kGPParamRegistersCount = static const Register kGPReturnRegisters[] = {GP_RETURN_REGISTERS};
static_cast<int>(arraysize(kGPParamRegisters)); static const int kGPReturnRegistersCount =
static_cast<int>(arraysize(kGPReturnRegisters));
#else #else
static const Register* kGPParamRegisters = nullptr; static const Register* kGPReturnRegisters = nullptr;
static const int kGPParamRegistersCount = 0; static const int kGPReturnRegistersCount = 0;
#endif #endif
#ifdef FP_PARAM_REGISTERS #ifdef FP_RETURN_REGISTERS
static const DoubleRegister kFPParamRegisters[] = {FP_PARAM_REGISTERS}; static const DoubleRegister kFPReturnRegisters[] = {FP_RETURN_REGISTERS};
static const int kFPParamRegistersCount = static const int kFPReturnRegistersCount =
static_cast<int>(arraysize(kFPParamRegisters)); static_cast<int>(arraysize(kFPReturnRegisters));
#else #else
static const DoubleRegister* kFPParamRegisters = nullptr; static const DoubleRegister* kFPReturnRegisters = nullptr;
static const int kFPParamRegistersCount = 0; static const int kFPReturnRegistersCount = 0;
#endif #endif
Allocator params(kGPParamRegisters, kGPParamRegistersCount, kFPParamRegisters, new (allocated_ptr) Allocator(kGPReturnRegisters, kGPReturnRegistersCount,
kFPParamRegistersCount); kFPReturnRegisters, kFPReturnRegistersCount);
}
};
return params; static base::LazyInstance<Allocator, ReturnRegistersCreateTrait>::type
} return_registers = LAZY_INSTANCE_INITIALIZER;
// General code uses the above configuration data. // General code uses the above configuration data.
CallDescriptor* ModuleEnv::GetWasmCallDescriptor(Zone* zone, CallDescriptor* ModuleEnv::GetWasmCallDescriptor(Zone* zone,
...@@ -262,7 +269,7 @@ CallDescriptor* ModuleEnv::GetWasmCallDescriptor(Zone* zone, ...@@ -262,7 +269,7 @@ CallDescriptor* ModuleEnv::GetWasmCallDescriptor(Zone* zone,
LocationSignature::Builder locations(zone, fsig->return_count(), LocationSignature::Builder locations(zone, fsig->return_count(),
fsig->parameter_count()); fsig->parameter_count());
Allocator rets = GetReturnRegisters(); Allocator rets = return_registers.Get();
// Add return location(s). // Add return location(s).
const int return_count = static_cast<int>(locations.return_count_); const int return_count = static_cast<int>(locations.return_count_);
...@@ -271,7 +278,7 @@ CallDescriptor* ModuleEnv::GetWasmCallDescriptor(Zone* zone, ...@@ -271,7 +278,7 @@ CallDescriptor* ModuleEnv::GetWasmCallDescriptor(Zone* zone,
locations.AddReturn(rets.Next(ret)); locations.AddReturn(rets.Next(ret));
} }
Allocator params = GetParameterRegisters(); Allocator params = parameter_registers.Get();
// Add register and/or stack parameter(s). // Add register and/or stack parameter(s).
const int parameter_count = static_cast<int>(fsig->parameter_count()); const int parameter_count = static_cast<int>(fsig->parameter_count());
...@@ -325,7 +332,7 @@ CallDescriptor* ModuleEnv::GetI32WasmCallDescriptor( ...@@ -325,7 +332,7 @@ CallDescriptor* ModuleEnv::GetI32WasmCallDescriptor(
LocationSignature::Builder locations(zone, return_count, parameter_count); LocationSignature::Builder locations(zone, return_count, parameter_count);
Allocator rets = GetReturnRegisters(); Allocator rets = return_registers.Get();
for (size_t i = 0; i < descriptor->ReturnCount(); i++) { for (size_t i = 0; i < descriptor->ReturnCount(); i++) {
if (descriptor->GetReturnType(i) == MachineType::Int64()) { if (descriptor->GetReturnType(i) == MachineType::Int64()) {
...@@ -338,7 +345,7 @@ CallDescriptor* ModuleEnv::GetI32WasmCallDescriptor( ...@@ -338,7 +345,7 @@ CallDescriptor* ModuleEnv::GetI32WasmCallDescriptor(
} }
} }
Allocator params = GetParameterRegisters(); Allocator params = parameter_registers.Get();
for (size_t i = 0; i < descriptor->ParameterCount(); i++) { for (size_t i = 0; i < descriptor->ParameterCount(); i++) {
if (descriptor->GetParameterType(i) == MachineType::Int64()) { if (descriptor->GetParameterType(i) == MachineType::Int64()) {
......
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