Revision: 5005
Author: [email protected]
Date: Thu Jul 1 15:12:37 2010
Log: [Isolates] Statics 7: ExternalReference*/Simulator/dtoa
- Fix up ExternalReference{Table|Encoder|Decoder} for multiple isolates.
- Define MULTIPLE_THREADS for dtoa.
- Fix up the simulator for multiple isolates.
Review URL: http://codereview.chromium.org/2864032
http://code.google.com/p/v8/source/detail?r=5005
Modified:
/branches/experimental/isolates/src/arm/cpu-arm.cc
/branches/experimental/isolates/src/arm/simulator-arm.cc
/branches/experimental/isolates/src/arm/simulator-arm.h
/branches/experimental/isolates/src/conversions.cc
/branches/experimental/isolates/src/dtoa-config.c
/branches/experimental/isolates/src/isolate.cc
/branches/experimental/isolates/src/isolate.h
/branches/experimental/isolates/src/serialize.cc
/branches/experimental/isolates/src/serialize.h
=======================================
--- /branches/experimental/isolates/src/arm/cpu-arm.cc Wed Jun 16 09:30:02
2010
+++ /branches/experimental/isolates/src/arm/cpu-arm.cc Thu Jul 1 15:12:37
2010
@@ -56,7 +56,8 @@
// that the Icache was flushed.
// None of this code ends up in the snapshot so there are no issues
// around whether or not to generate the code when building snapshots.
- assembler::arm::Simulator::FlushICache(start, size);
+ assembler::arm::Simulator::FlushICache(
+ Isolate::Current()->simulator_i_cache(), start, size);
#else
// Ideally, we would call
// syscall(__ARM_NR_cacheflush, start,
=======================================
--- /branches/experimental/isolates/src/arm/simulator-arm.cc Fri Jun 25
15:53:25 2010
+++ /branches/experimental/isolates/src/arm/simulator-arm.cc Thu Jul 1
15:12:37 2010
@@ -47,6 +47,7 @@
using ::v8::internal::OS;
using ::v8::internal::ReadLine;
using ::v8::internal::DeleteArray;
+using ::v8::internal::Isolate;
// This macro provides a platform independent use of sscanf. The reason for
// SScanF not being implemented in a platform independent way through
@@ -495,7 +496,9 @@
}
-void Simulator::FlushICache(void* start_addr, size_t size) {
+void Simulator::FlushICache(v8::internal::HashMap* i_cache,
+ void* start_addr,
+ size_t size) {
intptr_t start = reinterpret_cast<intptr_t>(start_addr);
int intra_line = (start & CachePage::kLineMask);
start -= intra_line;
@@ -504,22 +507,22 @@
int offset = (start & CachePage::kPageMask);
while (!AllOnOnePage(start, size - 1)) {
int bytes_to_flush = CachePage::kPageSize - offset;
- FlushOnePage(start, bytes_to_flush);
+ FlushOnePage(i_cache, start, bytes_to_flush);
start += bytes_to_flush;
size -= bytes_to_flush;
ASSERT_EQ(0, start & CachePage::kPageMask);
offset = 0;
}
if (size != 0) {
- FlushOnePage(start, size);
+ FlushOnePage(i_cache, start, size);
}
}
-CachePage* Simulator::GetCachePage(void* page) {
- v8::internal::HashMap::Entry* entry = i_cache_->Lookup(page,
- ICacheHash(page),
- true);
+CachePage* Simulator::GetCachePage(v8::internal::HashMap* i_cache, void*
page) {
+ v8::internal::HashMap::Entry* entry = i_cache->Lookup(page,
+ ICacheHash(page),
+ true);
if (entry->value == NULL) {
CachePage* new_page = new CachePage();
entry->value = new_page;
@@ -529,25 +532,27 @@
// Flush from start up to and not including start + size.
-void Simulator::FlushOnePage(intptr_t start, int size) {
+void Simulator::FlushOnePage(v8::internal::HashMap* i_cache,
+ intptr_t start,
+ int size) {
ASSERT(size <= CachePage::kPageSize);
ASSERT(AllOnOnePage(start, size - 1));
ASSERT((start & CachePage::kLineMask) == 0);
ASSERT((size & CachePage::kLineMask) == 0);
void* page = reinterpret_cast<void*>(start & (~CachePage::kPageMask));
int offset = (start & CachePage::kPageMask);
- CachePage* cache_page = GetCachePage(page);
+ CachePage* cache_page = GetCachePage(i_cache, page);
char* valid_bytemap = cache_page->ValidityByte(offset);
memset(valid_bytemap, CachePage::LINE_INVALID, size >>
CachePage::kLineShift);
}
-void Simulator::CheckICache(Instr* instr) {
+void Simulator::CheckICache(v8::internal::HashMap* i_cache, Instr* instr) {
intptr_t address = reinterpret_cast<intptr_t>(instr);
void* page = reinterpret_cast<void*>(address & (~CachePage::kPageMask));
void* line = reinterpret_cast<void*>(address & (~CachePage::kLineMask));
int offset = (address & CachePage::kPageMask);
- CachePage* cache_page = GetCachePage(page);
+ CachePage* cache_page = GetCachePage(i_cache, page);
char* cache_valid_byte = cache_page->ValidityByte(offset);
bool cache_hit = (*cache_valid_byte == CachePage::LINE_VALID);
char* cached_line = cache_page->CachedData(offset &
~CachePage::kLineMask);
@@ -562,29 +567,20 @@
*cache_valid_byte = CachePage::LINE_VALID;
}
}
-
-
-// Create one simulator per thread and keep it in thread local storage.
-static v8::internal::Thread::LocalStorageKey simulator_key;
-
-
-bool Simulator::initialized_ = false;
void Simulator::Initialize() {
- if (initialized_) return;
- simulator_key = v8::internal::Thread::CreateThreadLocalKey();
- initialized_ = true;
+ if (Isolate::Current()->simulator_initialized()) return;
+ Isolate::Current()->set_simulator_initialized(true);
::v8::internal::ExternalReference::set_redirector(&RedirectExternalReference);
}
-v8::internal::HashMap* Simulator::i_cache_ = NULL;
-
-
-Simulator::Simulator() {
+Simulator::Simulator() : isolate_(Isolate::Current()) {
+ i_cache_ = isolate_->simulator_i_cache();
if (i_cache_ == NULL) {
i_cache_ = new v8::internal::HashMap(&ICacheMatch);
+ isolate_->set_simulator_i_cache(i_cache_);
}
Initialize();
// Setup simulator support first. Some of this information is needed to
@@ -649,11 +645,13 @@
: external_function_(external_function),
swi_instruction_((AL << 28) | (0xf << 24) | call_rt_redirected),
fp_return_(fp_return),
- next_(list_) {
- Simulator::current()->
- FlushICache(reinterpret_cast<void*>(&swi_instruction_),
- Instr::kInstrSize);
- list_ = this;
+ next_(NULL) {
+ v8::internal::Isolate* isolate = Isolate::Current();
+ next_ = isolate->simulator_redirection();
+ Simulator::FlushICache(isolate->simulator_i_cache(),
+ reinterpret_cast<void*>(&swi_instruction_),
+ Instr::kInstrSize);
+ isolate->set_simulator_redirection(this);
}
void* address_of_swi_instruction() {
@@ -664,8 +662,9 @@
bool fp_return() { return fp_return_; }
static Redirection* Get(void* external_function, bool fp_return) {
- Redirection* current;
- for (current = list_; current != NULL; current = current->next_) {
+ Isolate* isolate = Isolate::Current();
+ Redirection* current = isolate->simulator_redirection();
+ for (; current != NULL; current = current->next_) {
if (current->external_function_ == external_function) return current;
}
return new Redirection(external_function, fp_return);
@@ -683,13 +682,9 @@
uint32_t swi_instruction_;
bool fp_return_;
Redirection* next_;
- static Redirection* list_;
};
-Redirection* Redirection::list_ = NULL;
-
-
void* Simulator::RedirectExternalReference(void* external_function,
bool fp_return) {
Redirection* redirection = Redirection::Get(external_function,
fp_return);
@@ -698,14 +693,16 @@
// Get the active Simulator for the current thread.
-Simulator* Simulator::current() {
+Simulator* Simulator::current(Isolate* isolate) {
+ v8::internal::Thread::LocalStorageKey* simulator_key =
+ Isolate::Current()->simulator_key();
Initialize();
Simulator* sim = reinterpret_cast<Simulator*>(
- v8::internal::Thread::GetThreadLocal(simulator_key));
+ v8::internal::Thread::GetThreadLocal(*simulator_key));
if (sim == NULL) {
// TODO(146): delete the simulator object when a thread goes away.
sim = new Simulator();
- v8::internal::Thread::SetThreadLocal(simulator_key, sim);
+ v8::internal::Thread::SetThreadLocal(*simulator_key, sim);
}
return sim;
}
@@ -2568,7 +2565,7 @@
// Executes the current instruction.
void Simulator::InstructionDecode(Instr* instr) {
if (v8::internal::FLAG_check_icache) {
- CheckICache(instr);
+ CheckICache(isolate_->simulator_i_cache(), instr);
}
pc_modified_ = false;
if (::v8::internal::FLAG_trace_sim) {
=======================================
--- /branches/experimental/isolates/src/arm/simulator-arm.h Fri May 7
13:02:57 2010
+++ /branches/experimental/isolates/src/arm/simulator-arm.h Thu Jul 1
15:12:37 2010
@@ -74,17 +74,17 @@
// When running with the simulator transition into simulated execution at
this
// point.
-#define CALL_GENERATED_CODE(entry, p0, p1, p2, p3, p4) \
- reinterpret_cast<Object*>( \
- assembler::arm::Simulator::current()->Call(FUNCTION_ADDR(entry), 5, \
- p0, p1, p2, p3, p4))
-
-#define CALL_GENERATED_REGEXP_CODE(entry, p0, p1, p2, p3, p4, p5, p6) \
- assembler::arm::Simulator::current()->Call( \
+#define CALL_GENERATED_CODE(entry, p0, p1, p2, p3,
p4) \
+
reinterpret_cast<Object*>(
\
+
assembler::arm::Simulator::current(Isolate::Current())-> \
+ Call(FUNCTION_ADDR(entry), 5, p0, p1, p2, p3, p4))
+
+#define CALL_GENERATED_REGEXP_CODE(entry, p0, p1, p2, p3, p4, p5,
p6) \
+
assembler::arm::Simulator::current(Isolate::Current())->Call(
\
FUNCTION_ADDR(entry), 7, p0, p1, p2, p3, p4, p5, p6)
-#define TRY_CATCH_FROM_ADDRESS(try_catch_address) \
- try_catch_address == NULL ? \
+#define
TRY_CATCH_FROM_ADDRESS(try_catch_address) \
+ try_catch_address ==
NULL ? \
NULL : *(reinterpret_cast<TryCatch**>(try_catch_address))
@@ -152,7 +152,7 @@
// The currently executing Simulator instance. Potentially there can be
one
// for each native thread.
- static Simulator* current();
+ static Simulator* current(v8::internal::Isolate* isolate);
// Accessors for register state. Reading the pc value adheres to the ARM
// architecture specification and is off by a 8 from the currently
executing
@@ -196,7 +196,8 @@
uintptr_t PopAddress();
// ICache checking.
- static void FlushICache(void* start, size_t size);
+ static void FlushICache(v8::internal::HashMap* i_cache, void* start,
+ size_t size);
private:
enum special_values {
@@ -279,9 +280,10 @@
void InstructionDecode(Instr* instr);
// ICache.
- static void CheckICache(Instr* instr);
- static void FlushOnePage(intptr_t start, int size);
- static CachePage* GetCachePage(void* page);
+ static void CheckICache(v8::internal::HashMap* i_cache, Instr* instr);
+ static void FlushOnePage(v8::internal::HashMap* i_cache, intptr_t start,
+ int size);
+ static CachePage* GetCachePage(v8::internal::HashMap* i_cache, void*
page);
// Runtime call support.
static void* RedirectExternalReference(void* external_function,
@@ -318,14 +320,15 @@
char* stack_;
bool pc_modified_;
int icount_;
- static bool initialized_;
// Icache simulation
- static v8::internal::HashMap* i_cache_;
+ v8::internal::HashMap* i_cache_;
// Registered breakpoints.
Instr* break_pc_;
instr_t break_instr_;
+
+ v8::internal::Isolate* isolate_;
};
} } // namespace assembler::arm
@@ -339,16 +342,19 @@
class SimulatorStack : public v8::internal::AllStatic {
public:
static inline uintptr_t JsLimitFromCLimit(uintptr_t c_limit) {
- return assembler::arm::Simulator::current()->StackLimit();
+ return assembler::arm::Simulator::current(
+ v8::internal::Isolate::Current())->StackLimit();
}
static inline uintptr_t RegisterCTryCatch(uintptr_t try_catch_address) {
- assembler::arm::Simulator* sim = assembler::arm::Simulator::current();
+ assembler::arm::Simulator* sim =
+
assembler::arm::Simulator::current(v8::internal::Isolate::Current());
return sim->PushAddress(try_catch_address);
}
static inline void UnregisterCTryCatch() {
- assembler::arm::Simulator::current()->PopAddress();
+ assembler::arm::Simulator::current(v8::internal::Isolate::Current())->
+ PopAddress();
}
};
=======================================
--- /branches/experimental/isolates/src/conversions.cc Thu Jun 17 06:14:39
2010
+++ /branches/experimental/isolates/src/conversions.cc Thu Jul 1 15:12:37
2010
@@ -1152,6 +1152,25 @@
builder.AddSubstring(decimal_buffer, decimal_pos);
return builder.Finalize();
}
+
+
+static Mutex* dtoa_lock_one = OS::CreateMutex();
+static Mutex* dtoa_lock_zero = OS::CreateMutex();
} } // namespace v8::internal
+
+
+extern "C" {
+void ACQUIRE_DTOA_LOCK(int n) {
+ ASSERT(n == 0 || n == 1);
+ (n == 0 ? v8::internal::dtoa_lock_zero :
v8::internal::dtoa_lock_one)->Lock();
+}
+
+
+void FREE_DTOA_LOCK(int n) {
+ ASSERT(n == 0 || n == 1);
+ (n == 0 ? v8::internal::dtoa_lock_zero : v8::internal::dtoa_lock_one)->
+ Unlock();
+}
+}
=======================================
--- /branches/experimental/isolates/src/dtoa-config.c Mon Jan 25 04:37:31
2010
+++ /branches/experimental/isolates/src/dtoa-config.c Thu Jul 1 15:12:37
2010
@@ -85,6 +85,10 @@
#define Long int
#endif /* V8_TARGET_ARCH_X64 */
+/* Definitions for dtoa's ACQUIRE_DTOA_LOCK and FREE_DTOA_LOCK are in
+ * conversions.cc. */
+#define MULTIPLE_THREADS
+
/* Make sure we use the David M. Gay version of strtod(). On Linux, we
* cannot use the same name (maybe the function does not have weak
* linkage?). */
=======================================
--- /branches/experimental/isolates/src/isolate.cc Thu Jul 1 14:55:46 2010
+++ /branches/experimental/isolates/src/isolate.cc Thu Jul 1 15:12:37 2010
@@ -266,6 +266,13 @@
zone_.isolate_ = this;
stack_guard_.isolate_ = this;
+#if defined(V8_TARGET_ARCH_ARM) && !defined(__arm__)
+ simulator_initialized_ = false;
+ simulator_i_cache_ = NULL;
+ simulator_key_ = Thread::CreateThreadLocalKey();
+ simulator_redirection_ = NULL;
+#endif
+
#ifdef DEBUG
// heap_histograms_ initializes itself.
memset(&js_spill_information_, 0, sizeof(js_spill_information_));
@@ -399,6 +406,10 @@
debug_ = NULL;
#endif
+#if defined(V8_TARGET_ARCH_ARM) && !defined(__arm__)
+ Thread::DeleteThreadLocalKey(simulator_key_);
+#endif
+
if (state_ == INITIALIZED) --number_of_isolates_;
}
=======================================
--- /branches/experimental/isolates/src/isolate.h Thu Jul 1 14:55:46 2010
+++ /branches/experimental/isolates/src/isolate.h Thu Jul 1 15:12:37 2010
@@ -45,6 +45,16 @@
#include "zone.h"
#include "../include/v8-debug.h"
+
+#if !defined(__arm__) && defined(V8_TARGET_ARCH_ARM)
+namespace assembler {
+namespace arm {
+class Redirection;
+}
+}
+#endif
+
+
namespace v8 {
namespace internal {
@@ -60,6 +70,7 @@
class CpuProfiler;
class Deserializer;
class EmptyStatement;
+class ExternalReferenceTable;
class FunctionInfoListener;
class HandleScopeImplementer;
class HeapProfiler;
@@ -197,6 +208,10 @@
/* VirtualFrame::SpilledScope state
*/ \
V(bool, is_virtual_frame_in_spilled_scope, false)
+#if !defined(__arm__)
+class HashMap;
+#endif
+
#else
#define ISOLATE_PLATFORM_INIT_LIST(V)
@@ -276,6 +291,8 @@
V(Object*, string_stream_current_security_token,
NULL) \
/* TODO(isolates): Release this on destruction?
*/ \
V(int*, irregexp_interpreter_backtrack_stack_cache,
NULL) \
+ /* Serializer state.
*/ \
+ V(ExternalReferenceTable*, external_reference_table,
NULL) \
ISOLATE_PLATFORM_INIT_LIST(V)
\
ISOLATE_LOGGING_INIT_LIST(V)
\
ISOLATE_DEBUGGER_INIT_LIST(V)
@@ -704,6 +721,29 @@
int* code_kind_statistics() { return code_kind_statistics_; }
#endif
+#if defined(V8_TARGET_ARCH_ARM) && !defined(__arm__)
+ v8::internal::Thread::LocalStorageKey* simulator_key() {
+ return &simulator_key_;
+ }
+
+ bool simulator_initialized() { return simulator_initialized_; }
+ void set_simulator_initialized(bool initialized) {
+ simulator_initialized_ = initialized;
+ }
+
+ HashMap* simulator_i_cache() { return simulator_i_cache_; }
+ void set_simulator_i_cache(HashMap* hash_map) {
+ simulator_i_cache_ = hash_map;
+ }
+
+ assembler::arm::Redirection* simulator_redirection() {
+ return simulator_redirection_;
+ }
+ void set_simulator_redirection(assembler::arm::Redirection* redirection)
{
+ simulator_redirection_ = redirection;
+ }
+#endif
+
bool IsDefaultIsolate() { return this == global_isolate_; }
// SerializerDeserializer state.
@@ -808,6 +848,13 @@
ZoneObjectList frame_element_constant_list_;
ZoneObjectList result_constant_list_;
+#if defined(V8_TARGET_ARCH_ARM) && !defined(__arm__)
+ // Create one simulator per thread and keep it in thread local storage.
+ v8::internal::Thread::LocalStorageKey simulator_key_;
+ bool simulator_initialized_;
+ HashMap* simulator_i_cache_;
+ assembler::arm::Redirection* simulator_redirection_;
+#endif
#ifdef DEBUG
// A static array of histogram info for each type.
=======================================
--- /branches/experimental/isolates/src/serialize.cc Thu Jul 1 11:02:03
2010
+++ /branches/experimental/isolates/src/serialize.cc Thu Jul 1 15:12:37
2010
@@ -67,9 +67,14 @@
// hashmaps in ExternalReferenceEncoder and ExternalReferenceDecoder.
class ExternalReferenceTable {
public:
- static ExternalReferenceTable* instance() {
- if (!instance_) instance_ = new ExternalReferenceTable();
- return instance_;
+ static ExternalReferenceTable* instance(Isolate* isolate) {
+ ExternalReferenceTable* external_reference_table =
+ isolate->external_reference_table();
+ if (external_reference_table == NULL) {
+ external_reference_table = new ExternalReferenceTable(isolate);
+ isolate->set_external_reference_table(external_reference_table);
+ }
+ return external_reference_table;
}
int size() const { return refs_.length(); }
@@ -83,9 +88,9 @@
int max_id(int code) { return max_id_[code]; }
private:
- static ExternalReferenceTable* instance_;
-
- ExternalReferenceTable() : refs_(64) { PopulateTable(); }
+ explicit ExternalReferenceTable(Isolate* isolate) : refs_(64) {
+ PopulateTable(isolate);
+ }
~ExternalReferenceTable() { }
struct ExternalReferenceEntry {
@@ -94,7 +99,7 @@
const char* name;
};
- void PopulateTable();
+ void PopulateTable(Isolate* isolate);
// For a few types of references, we can get their address from their id.
void AddFromId(TypeCode type, uint16_t id, const char* name);
@@ -107,9 +112,6 @@
};
-ExternalReferenceTable* ExternalReferenceTable::instance_ = NULL;
-
-
void ExternalReferenceTable::AddFromId(TypeCode type,
uint16_t id,
const char* name) {
@@ -158,9 +160,7 @@
}
-void ExternalReferenceTable::PopulateTable() {
- Isolate* isolate = Isolate::Current();
-
+void ExternalReferenceTable::PopulateTable(Isolate* isolate) {
for (int type_code = 0; type_code < kTypeCodeCount; type_code++) {
max_id_[type_code] = 0;
}
@@ -469,9 +469,10 @@
ExternalReferenceEncoder::ExternalReferenceEncoder()
- : encodings_(Match) {
+ : encodings_(Match),
+ isolate_(Isolate::Current()) {
ExternalReferenceTable* external_references =
- ExternalReferenceTable::instance();
+ ExternalReferenceTable::instance(isolate_);
for (int i = 0; i < external_references->size(); ++i) {
Put(external_references->address(i), i);
}
@@ -480,20 +481,22 @@
uint32_t ExternalReferenceEncoder::Encode(Address key) const {
int index = IndexOf(key);
- return index >=0 ? ExternalReferenceTable::instance()->code(index) : 0;
+ return index >= 0 ?
+ ExternalReferenceTable::instance(isolate_)->code(index) : 0;
}
const char* ExternalReferenceEncoder::NameOfAddress(Address key) const {
int index = IndexOf(key);
- return index >=0 ? ExternalReferenceTable::instance()->name(index) :
NULL;
+ return index >= 0 ?
+ ExternalReferenceTable::instance(isolate_)->name(index) : NULL;
}
int ExternalReferenceEncoder::IndexOf(Address key) const {
if (key == NULL) return -1;
HashMap::Entry* entry =
- const_cast<HashMap &>(encodings_).Lookup(key, Hash(key), false);
+ const_cast<HashMap&>(encodings_).Lookup(key, Hash(key), false);
return entry == NULL
? -1
: static_cast<int>(reinterpret_cast<intptr_t>(entry->value));
@@ -507,9 +510,10 @@
ExternalReferenceDecoder::ExternalReferenceDecoder()
- : encodings_(NewArray<Address*>(kTypeCodeCount)) {
+ : encodings_(NewArray<Address*>(kTypeCodeCount)),
+ isolate_(Isolate::Current()) {
ExternalReferenceTable* external_references =
- ExternalReferenceTable::instance();
+ ExternalReferenceTable::instance(isolate_);
for (int type = kFirstTypeCode; type < kTypeCodeCount; ++type) {
int max = external_references->max_id(type) + 1;
encodings_[type] = NewArray<Address>(max + 1);
=======================================
--- /branches/experimental/isolates/src/serialize.h Tue Jun 8 10:29:06 2010
+++ /branches/experimental/isolates/src/serialize.h Thu Jul 1 15:12:37 2010
@@ -79,6 +79,8 @@
static bool Match(void* key1, void* key2) { return key1 == key2; }
void Put(Address key, int index);
+
+ Isolate* isolate_;
};
@@ -105,6 +107,8 @@
void Put(uint32_t key, Address value) {
*Lookup(key) = value;
}
+
+ Isolate* isolate_;
};
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev