Revision: 20855
Author: [email protected]
Date: Thu Apr 17 14:45:06 2014 UTC
Log: Serializer enable/disable flags need thread safety.
BUG=
[email protected], [email protected]
Review URL: https://codereview.chromium.org/240193002
http://code.google.com/p/v8/source/detail?r=20855
Modified:
/branches/bleeding_edge/src/arm/assembler-arm.cc
/branches/bleeding_edge/src/arm/assembler-arm.h
/branches/bleeding_edge/src/arm64/assembler-arm64.cc
/branches/bleeding_edge/src/flags.cc
/branches/bleeding_edge/src/ia32/assembler-ia32.cc
/branches/bleeding_edge/src/mips/assembler-mips.cc
/branches/bleeding_edge/src/mksnapshot.cc
/branches/bleeding_edge/src/serialize.cc
/branches/bleeding_edge/src/serialize.h
/branches/bleeding_edge/src/v8.cc
/branches/bleeding_edge/src/x64/assembler-x64.cc
/branches/bleeding_edge/src/x64/macro-assembler-x64.cc
/branches/bleeding_edge/test/cctest/test-serialize.cc
=======================================
--- /branches/bleeding_edge/src/arm/assembler-arm.cc Wed Apr 16 11:38:56
2014 UTC
+++ /branches/bleeding_edge/src/arm/assembler-arm.cc Thu Apr 17 14:45:06
2014 UTC
@@ -48,6 +48,7 @@
#ifdef DEBUG
bool CpuFeatures::initialized_ = false;
#endif
+bool CpuFeatures::hint_creating_snapshot_ = false;
unsigned CpuFeatures::supported_ = 0;
unsigned CpuFeatures::found_by_runtime_probing_only_ = 0;
unsigned CpuFeatures::cross_compile_ = 0;
@@ -98,12 +99,29 @@
return VFPRegisters::Name(index, true);
}
+
+
+void CpuFeatures::SetHintCreatingSnapshot() {
+ hint_creating_snapshot_ = true;
+}
+
+
+void CpuFeatures::ProbeWithoutIsolate() {
+ Probe(hint_creating_snapshot_);
+}
void CpuFeatures::Probe() {
+ // The Serializer can only be queried after isolate initialization.
+ Probe(Serializer::enabled());
+}
+
+
+void CpuFeatures::Probe(bool serializer_enabled) {
uint64_t standard_features = static_cast<unsigned>(
OS::CpuFeaturesImpliedByPlatform()) | CpuFeaturesImpliedByCompiler();
- ASSERT(supported_ == 0 || supported_ == standard_features);
+ ASSERT(supported_ == 0 ||
+ (supported_ & standard_features) == standard_features);
#ifdef DEBUG
initialized_ = true;
#endif
@@ -113,7 +131,7 @@
// snapshot.
supported_ |= standard_features;
- if (Serializer::enabled()) {
+ if (serializer_enabled) {
// No probing for features if we might serialize (generate snapshot).
printf(" ");
PrintFeatures();
@@ -1079,11 +1097,6 @@
// encoded.
bool Operand::must_output_reloc_info(const Assembler* assembler) const {
if (rmode_ == RelocInfo::EXTERNAL_REFERENCE) {
-#ifdef DEBUG
- if (!Serializer::enabled()) {
- Serializer::TooLateToEnableNow();
- }
-#endif // def DEBUG
if (assembler != NULL && assembler->predictable_code_size()) return
true;
return Serializer::enabled();
} else if (RelocInfo::IsNone(rmode_)) {
@@ -3267,11 +3280,6 @@
if (!RelocInfo::IsNone(rinfo.rmode())) {
// Don't record external references unless the heap will be serialized.
if (rinfo.rmode() == RelocInfo::EXTERNAL_REFERENCE) {
-#ifdef DEBUG
- if (!Serializer::enabled()) {
- Serializer::TooLateToEnableNow();
- }
-#endif
if (!Serializer::enabled() && !emit_debug_code()) {
return;
}
=======================================
--- /branches/bleeding_edge/src/arm/assembler-arm.h Wed Apr 16 11:38:56
2014 UTC
+++ /branches/bleeding_edge/src/arm/assembler-arm.h Thu Apr 17 14:45:06
2014 UTC
@@ -58,6 +58,11 @@
// is enabled (snapshots must be portable).
static void Probe();
+ // A special case for printing target and features, which we want to do
+ // before initializing the isolate
+ static void SetHintCreatingSnapshot();
+ static void ProbeWithoutIsolate();
+
// Display target use when compiling.
static void PrintTarget();
@@ -94,6 +99,9 @@
}
private:
+ static void Probe(bool serializer_enabled);
+ static bool hint_creating_snapshot_;
+
static bool Check(CpuFeature f, unsigned set) {
return (set & flag2set(f)) != 0;
}
=======================================
--- /branches/bleeding_edge/src/arm64/assembler-arm64.cc Wed Apr 16
11:38:56 2014 UTC
+++ /branches/bleeding_edge/src/arm64/assembler-arm64.cc Thu Apr 17
14:45:06 2014 UTC
@@ -273,11 +273,6 @@
bool Operand::NeedsRelocation() const {
if (rmode_ == RelocInfo::EXTERNAL_REFERENCE) {
-#ifdef DEBUG
- if (!Serializer::enabled()) {
- Serializer::TooLateToEnableNow();
- }
-#endif
return Serializer::enabled();
}
@@ -1970,9 +1965,6 @@
// Don't generate simulator specific code if we are building a snapshot,
which
// might be run on real hardware.
if (!Serializer::enabled()) {
-#ifdef DEBUG
- Serializer::TooLateToEnableNow();
-#endif
// The arguments to the debug marker need to be contiguous in memory,
so
// make sure we don't try to emit pools.
BlockPoolsScope scope(this);
@@ -2525,11 +2517,6 @@
if (!RelocInfo::IsNone(rmode)) {
// Don't record external references unless the heap will be serialized.
if (rmode == RelocInfo::EXTERNAL_REFERENCE) {
-#ifdef DEBUG
- if (!Serializer::enabled()) {
- Serializer::TooLateToEnableNow();
- }
-#endif
if (!Serializer::enabled() && !emit_debug_code()) {
return;
}
=======================================
--- /branches/bleeding_edge/src/flags.cc Mon Dec 9 07:41:20 2013 UTC
+++ /branches/bleeding_edge/src/flags.cc Thu Apr 17 14:45:06 2014 UTC
@@ -545,7 +545,7 @@
void FlagList::PrintHelp() {
#if V8_TARGET_ARCH_ARM
CpuFeatures::PrintTarget();
- CpuFeatures::Probe();
+ CpuFeatures::ProbeWithoutIsolate();
CpuFeatures::PrintFeatures();
#endif // V8_TARGET_ARCH_ARM
=======================================
--- /branches/bleeding_edge/src/ia32/assembler-ia32.cc Wed Apr 16 11:38:56
2014 UTC
+++ /branches/bleeding_edge/src/ia32/assembler-ia32.cc Thu Apr 17 14:45:06
2014 UTC
@@ -2703,11 +2703,6 @@
ASSERT(!RelocInfo::IsNone(rmode));
// Don't record external references unless the heap will be serialized.
if (rmode == RelocInfo::EXTERNAL_REFERENCE) {
-#ifdef DEBUG
- if (!Serializer::enabled()) {
- Serializer::TooLateToEnableNow();
- }
-#endif
if (!Serializer::enabled() && !emit_debug_code()) {
return;
}
=======================================
--- /branches/bleeding_edge/src/mips/assembler-mips.cc Wed Apr 16 11:38:56
2014 UTC
+++ /branches/bleeding_edge/src/mips/assembler-mips.cc Thu Apr 17 14:45:06
2014 UTC
@@ -105,7 +105,8 @@
void CpuFeatures::Probe() {
unsigned standard_features = (OS::CpuFeaturesImpliedByPlatform() |
CpuFeaturesImpliedByCompiler());
- ASSERT(supported_ == 0 || supported_ == standard_features);
+ ASSERT(supported_ == 0 ||
+ (supported_ & standard_features) == standard_features);
#ifdef DEBUG
initialized_ = true;
#endif
=======================================
--- /branches/bleeding_edge/src/mksnapshot.cc Wed Jan 29 13:30:38 2014 UTC
+++ /branches/bleeding_edge/src/mksnapshot.cc Thu Apr 17 14:45:06 2014 UTC
@@ -41,6 +41,10 @@
#include "serialize.h"
#include "list.h"
+#if V8_TARGET_ARCH_ARM
+#include "arm/assembler-arm-inl.h"
+#endif
+
using namespace v8;
@@ -272,6 +276,12 @@
// By default, log code create information in the snapshot.
i::FLAG_log_code = true;
+#if V8_TARGET_ARCH_ARM
+ // Printing flags on ARM requires knowing if we intend to enable
+ // the serializer or not.
+ v8::internal::CpuFeatures::SetHintCreatingSnapshot();
+#endif
+
// Print the usage if an error occurs when parsing the command line
// flags or if the help flag is set.
int result = i::FlagList::SetFlagsFromCommandLine(&argc, argv, true);
@@ -293,7 +303,7 @@
Isolate* isolate = v8::Isolate::New();
isolate->Enter();
i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
- i::Serializer::Enable(internal_isolate);
+ i::Serializer::RequestEnable(internal_isolate);
Persistent<Context> context;
{
HandleScope handle_scope(isolate);
=======================================
--- /branches/bleeding_edge/src/serialize.cc Wed Apr 16 12:01:38 2014 UTC
+++ /branches/bleeding_edge/src/serialize.cc Thu Apr 17 14:45:06 2014 UTC
@@ -649,10 +649,7 @@
DeleteArray(encodings_);
}
-
-bool Serializer::serialization_enabled_ = false;
-bool Serializer::too_late_to_enable_now_ = false;
-
+AtomicWord Serializer::serialization_state_ =
SERIALIZER_STATE_UNINITIALIZED;
class CodeAddressMap: public CodeEventLogger {
public:
@@ -765,22 +762,42 @@
CodeAddressMap* Serializer::code_address_map_ = NULL;
-void Serializer::Enable(Isolate* isolate) {
- if (!serialization_enabled_) {
- ASSERT(!too_late_to_enable_now_);
- }
- if (serialization_enabled_) return;
- serialization_enabled_ = true;
+void Serializer::RequestEnable(Isolate* isolate) {
isolate->InitializeLoggingAndCounters();
code_address_map_ = new CodeAddressMap(isolate);
}
-void Serializer::Disable() {
- if (!serialization_enabled_) return;
- serialization_enabled_ = false;
- delete code_address_map_;
- code_address_map_ = NULL;
+void Serializer::InitializeOncePerProcess() {
+ // InitializeOncePerProcess is called by V8::InitializeOncePerProcess, a
+ // method guaranteed to be called only once in a process lifetime.
+ // serialization_state_ is read by many threads, hence the use of
+ // Atomic primitives. Here, we don't need a barrier or mutex to
+ // write it because V8 initialization is done by one thread, and gates
+ // all reads of serialization_state_.
+ ASSERT(NoBarrier_Load(&serialization_state_) ==
+ SERIALIZER_STATE_UNINITIALIZED);
+ SerializationState state = code_address_map_
+ ? SERIALIZER_STATE_ENABLED
+ : SERIALIZER_STATE_DISABLED;
+ NoBarrier_Store(&serialization_state_, state);
+}
+
+
+void Serializer::TearDown() {
+ // TearDown is called by V8::TearDown() for the default isolate. It's
safe
+ // to shut down the serializer by that point. Just to be safe, we restore
+ // serialization_state_ to uninitialized.
+ ASSERT(NoBarrier_Load(&serialization_state_) !=
+ SERIALIZER_STATE_UNINITIALIZED);
+ if (code_address_map_) {
+ ASSERT(NoBarrier_Load(&serialization_state_) ==
+ SERIALIZER_STATE_ENABLED);
+ delete code_address_map_;
+ code_address_map_ = NULL;
+ }
+
+ NoBarrier_Store(&serialization_state_, SERIALIZER_STATE_UNINITIALIZED);
}
=======================================
--- /branches/bleeding_edge/src/serialize.h Tue Apr 15 14:48:21 2014 UTC
+++ /branches/bleeding_edge/src/serialize.h Thu Apr 17 14:45:06 2014 UTC
@@ -470,13 +470,16 @@
}
Isolate* isolate() const { return isolate_; }
- static void Enable(Isolate* isolate);
- static void Disable();
+ static void RequestEnable(Isolate* isolate);
+ static void InitializeOncePerProcess();
+ static void TearDown();
- // Call this when you have made use of the fact that there is no
serialization
- // going on.
- static void TooLateToEnableNow() { too_late_to_enable_now_ = true; }
- static bool enabled() { return serialization_enabled_; }
+ static bool enabled() {
+ SerializationState state = static_cast<SerializationState>(
+ NoBarrier_Load(&serialization_state_));
+ ASSERT(state != SERIALIZER_STATE_UNINITIALIZED);
+ return state == SERIALIZER_STATE_ENABLED;
+ }
SerializationAddressMapper* address_mapper() { return &address_mapper_; }
void PutRoot(int index,
HeapObject* object,
@@ -574,9 +577,15 @@
int fullness_[LAST_SPACE + 1];
SnapshotByteSink* sink_;
ExternalReferenceEncoder* external_reference_encoder_;
- static bool serialization_enabled_;
- // Did we already make use of the fact that serialization was not
enabled?
- static bool too_late_to_enable_now_;
+
+ enum SerializationState {
+ SERIALIZER_STATE_UNINITIALIZED = 0,
+ SERIALIZER_STATE_DISABLED = 1,
+ SERIALIZER_STATE_ENABLED = 2
+ };
+
+ static AtomicWord serialization_state_;
+
SerializationAddressMapper address_mapper_;
intptr_t root_index_wave_front_;
void Pad();
=======================================
--- /branches/bleeding_edge/src/v8.cc Wed Apr 16 12:01:38 2014 UTC
+++ /branches/bleeding_edge/src/v8.cc Thu Apr 17 14:45:06 2014 UTC
@@ -98,6 +98,7 @@
call_completed_callbacks_ = NULL;
Sampler::TearDown();
+ Serializer::TearDown();
#ifdef V8_USE_DEFAULT_PLATFORM
DefaultPlatform* platform = static_cast<DefaultPlatform*>(platform_);
@@ -172,6 +173,7 @@
void V8::InitializeOncePerProcessImpl() {
FlagList::EnforceFlagImplications();
+ Serializer::InitializeOncePerProcess();
if (FLAG_predictable && FLAG_random_seed == 0) {
// Avoid random seeds in predictable mode.
=======================================
--- /branches/bleeding_edge/src/x64/assembler-x64.cc Wed Apr 16 11:38:56
2014 UTC
+++ /branches/bleeding_edge/src/x64/assembler-x64.cc Thu Apr 17 14:45:06
2014 UTC
@@ -2953,11 +2953,6 @@
ASSERT(!RelocInfo::IsNone(rmode));
if (rmode == RelocInfo::EXTERNAL_REFERENCE) {
// Don't record external references unless the heap will be serialized.
-#ifdef DEBUG
- if (!Serializer::enabled()) {
- Serializer::TooLateToEnableNow();
- }
-#endif
if (!Serializer::enabled() && !emit_debug_code()) {
return;
}
=======================================
--- /branches/bleeding_edge/src/x64/macro-assembler-x64.cc Fri Apr 11
06:32:06 2014 UTC
+++ /branches/bleeding_edge/src/x64/macro-assembler-x64.cc Thu Apr 17
14:45:06 2014 UTC
@@ -75,7 +75,6 @@
if (root_array_available_ && !Serializer::enabled()) {
intptr_t delta = RootRegisterDelta(target);
if (delta != kInvalidRootRegisterDelta && is_int32(delta)) {
- Serializer::TooLateToEnableNow();
return Operand(kRootRegister, static_cast<int32_t>(delta));
}
}
@@ -88,7 +87,6 @@
if (root_array_available_ && !Serializer::enabled()) {
intptr_t delta = RootRegisterDelta(source);
if (delta != kInvalidRootRegisterDelta && is_int32(delta)) {
- Serializer::TooLateToEnableNow();
movp(destination, Operand(kRootRegister,
static_cast<int32_t>(delta)));
return;
}
@@ -107,7 +105,6 @@
if (root_array_available_ && !Serializer::enabled()) {
intptr_t delta = RootRegisterDelta(destination);
if (delta != kInvalidRootRegisterDelta && is_int32(delta)) {
- Serializer::TooLateToEnableNow();
movp(Operand(kRootRegister, static_cast<int32_t>(delta)), source);
return;
}
@@ -127,7 +124,6 @@
if (root_array_available_ && !Serializer::enabled()) {
intptr_t delta = RootRegisterDelta(source);
if (delta != kInvalidRootRegisterDelta && is_int32(delta)) {
- Serializer::TooLateToEnableNow();
leap(destination, Operand(kRootRegister,
static_cast<int32_t>(delta)));
return;
}
@@ -144,7 +140,6 @@
// instruction below.
intptr_t delta = RootRegisterDelta(source);
if (delta != kInvalidRootRegisterDelta && is_int32(delta)) {
- Serializer::TooLateToEnableNow();
// Operand is leap(scratch, Operand(kRootRegister, delta));
// Opcodes : REX.W 8D ModRM Disp8/Disp32 - 4 or 7.
int size = 4;
=======================================
--- /branches/bleeding_edge/test/cctest/test-serialize.cc Fri Nov 22
12:43:17 2013 UTC
+++ /branches/bleeding_edge/test/cctest/test-serialize.cc Thu Apr 17
14:45:06 2014 UTC
@@ -266,7 +266,7 @@
// Test that the whole heap can be serialized.
TEST(Serialize) {
if (!Snapshot::HaveASnapshotToStartFrom()) {
- Serializer::Enable(CcTest::i_isolate());
+ Serializer::RequestEnable(CcTest::i_isolate());
v8::V8::Initialize();
Serialize();
}
@@ -276,7 +276,7 @@
// Test that heap serialization is non-destructive.
TEST(SerializeTwice) {
if (!Snapshot::HaveASnapshotToStartFrom()) {
- Serializer::Enable(CcTest::i_isolate());
+ Serializer::RequestEnable(CcTest::i_isolate());
v8::V8::Initialize();
Serialize();
Serialize();
@@ -375,7 +375,7 @@
TEST(PartialSerialization) {
if (!Snapshot::HaveASnapshotToStartFrom()) {
Isolate* isolate = CcTest::i_isolate();
- Serializer::Enable(isolate);
+ Serializer::RequestEnable(isolate);
v8::V8::Initialize();
v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
Heap* heap = isolate->heap();
@@ -526,7 +526,7 @@
TEST(ContextSerialization) {
if (!Snapshot::HaveASnapshotToStartFrom()) {
Isolate* isolate = CcTest::i_isolate();
- Serializer::Enable(isolate);
+ Serializer::RequestEnable(isolate);
v8::V8::Initialize();
v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
Heap* heap = isolate->heap();
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.