diff --git a/SConstruct b/SConstruct index a36a96f9b3..820c1a1c72 100644 --- a/SConstruct +++ b/SConstruct @@ -207,7 +207,6 @@ LIBRARY_FLAGS = { 'simulator:arm': { 'CCFLAGS': ['-m32'], 'LINKFLAGS': ['-m32'], - 'CPPDEFINES': ['USE_SIMULATOR'] }, 'arch:mips': { 'CPPDEFINES': ['V8_TARGET_ARCH_MIPS'], @@ -219,7 +218,6 @@ LIBRARY_FLAGS = { 'simulator:mips': { 'CCFLAGS': ['-m32'], 'LINKFLAGS': ['-m32'], - 'CPPDEFINES': ['USE_SIMULATOR'] }, 'arch:x64': { 'CPPDEFINES': ['V8_TARGET_ARCH_X64'], diff --git a/src/arm/cpu-arm.cc b/src/arm/cpu-arm.cc index 3d3e6ae9d4..a3bf48328d 100644 --- a/src/arm/cpu-arm.cc +++ b/src/arm/cpu-arm.cc @@ -36,10 +36,7 @@ #include "cpu.h" #include "macro-assembler.h" - -#ifndef __arm__ -#include "simulator-arm.h" // for cache flushing. -#endif +#include "simulator.h" // for cache flushing. namespace v8 { namespace internal { @@ -50,7 +47,7 @@ void CPU::Setup() { void CPU::FlushICache(void* start, size_t size) { -#if !defined (__arm__) +#if defined (USE_SIMULATOR) // Not generating ARM instructions for C-code. This means that we are // building an ARM emulator based target. We should notify the simulator // that the Icache was flushed. diff --git a/src/arm/simulator-arm.cc b/src/arm/simulator-arm.cc index 84d9d01d08..534e394af1 100644 --- a/src/arm/simulator-arm.cc +++ b/src/arm/simulator-arm.cc @@ -37,7 +37,7 @@ #include "arm/constants-arm.h" #include "arm/simulator-arm.h" -#if !defined(__arm__) || defined(USE_SIMULATOR) +#if defined(USE_SIMULATOR) // Only build the simulator if not compiling for real ARM hardware. namespace assembler { @@ -2840,6 +2840,6 @@ uintptr_t Simulator::PopAddress() { } } // namespace assembler::arm -#endif // !__arm__ || USE_SIMULATOR +#endif // USE_SIMULATOR #endif // V8_TARGET_ARCH_ARM diff --git a/src/arm/simulator-arm.h b/src/arm/simulator-arm.h index d4c8250b33..e0658fc997 100644 --- a/src/arm/simulator-arm.h +++ b/src/arm/simulator-arm.h @@ -38,12 +38,24 @@ #include "allocation.h" -#if defined(__arm__) && !defined(USE_SIMULATOR) +#if !defined(USE_SIMULATOR) +// Running without a simulator on a native arm platform. + +namespace v8 { +namespace internal { // When running without a simulator we call the entry directly. #define CALL_GENERATED_CODE(entry, p0, p1, p2, p3, p4) \ (entry(p0, p1, p2, p3, p4)) +// Call the generated regexp code directly. The entry function pointer should +// expect seven int/pointer sized arguments and return an int. +#define CALL_GENERATED_REGEXP_CODE(entry, p0, p1, p2, p3, p4, p5, p6) \ + (entry(p0, p1, p2, p3, p4, p5, p6)) + +#define TRY_CATCH_FROM_ADDRESS(try_catch_address) \ + (reinterpret_cast(try_catch_address)) + // The stack limit beyond which we will throw stack overflow errors in // generated code. Because generated code on arm uses the C stack, we // just use the C stack limit. @@ -60,38 +72,14 @@ class SimulatorStack : public v8::internal::AllStatic { static inline void UnregisterCTryCatch() { } }; +} } // namespace v8::internal -// Call the generated regexp code directly. The entry function pointer should -// expect eight int/pointer sized arguments and return an int. -#define CALL_GENERATED_REGEXP_CODE(entry, p0, p1, p2, p3, p4, p5, p6) \ - entry(p0, p1, p2, p3, p4, p5, p6) - -#define TRY_CATCH_FROM_ADDRESS(try_catch_address) \ - reinterpret_cast(try_catch_address) - - -#else // !defined(__arm__) || defined(USE_SIMULATOR) - -// When running with the simulator transition into simulated execution at this -// point. -#define CALL_GENERATED_CODE(entry, p0, p1, p2, p3, p4) \ - reinterpret_cast( \ - 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( \ - FUNCTION_ADDR(entry), 7, p0, p1, p2, p3, p4, p5, p6) - -#define TRY_CATCH_FROM_ADDRESS(try_catch_address) \ - try_catch_address == NULL ? \ - NULL : *(reinterpret_cast(try_catch_address)) - +#else // !defined(USE_SIMULATOR) +// Running with a simulator. #include "constants-arm.h" #include "hashmap.h" - namespace assembler { namespace arm { @@ -334,6 +322,24 @@ class Simulator { } } // namespace assembler::arm +namespace v8 { +namespace internal { + +// When running with the simulator transition into simulated execution at this +// point. +#define CALL_GENERATED_CODE(entry, p0, p1, p2, p3, p4) \ + reinterpret_cast(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( \ + FUNCTION_ADDR(entry), 7, p0, p1, p2, p3, p4, p5, p6) + +#define TRY_CATCH_FROM_ADDRESS(try_catch_address) \ + try_catch_address == \ + NULL ? NULL : *(reinterpret_cast(try_catch_address)) + + // The simulator has its own stack. Thus it has a different stack limit from // the C-based native code. Setting the c_limit to indicate a very small // stack cause stack overflow errors, since the simulator ignores the input. @@ -355,7 +361,7 @@ class SimulatorStack : public v8::internal::AllStatic { } }; +} } // namespace v8::internal -#endif // !defined(__arm__) || defined(USE_SIMULATOR) - +#endif // !defined(USE_SIMULATOR) #endif // V8_ARM_SIMULATOR_ARM_H_ diff --git a/src/globals.h b/src/globals.h index 6dd5475d23..ee9ddac0ae 100644 --- a/src/globals.h +++ b/src/globals.h @@ -93,6 +93,14 @@ namespace internal { #error Target architecture mips is only supported on mips and ia32 host #endif +// Determine whether we are running in a simulated environment. +#if (defined(V8_TARGET_ARCH_ARM) && !defined(V8_HOST_ARCH_ARM)) +#define USE_SIMULATOR 1 +#endif +#if (defined(V8_TARGET_ARCH_MIPS) && !defined(V8_HOST_ARCH_MIPS)) +#define USE_SIMULATOR 1 +#endif + // Define unaligned read for the target architectures supporting it. #if defined(V8_TARGET_ARCH_X64) || defined(V8_TARGET_ARCH_IA32) #define V8_TARGET_CAN_READ_UNALIGNED 1 diff --git a/src/ia32/simulator-ia32.h b/src/ia32/simulator-ia32.h index 94ef7bff97..88d0b6187f 100644 --- a/src/ia32/simulator-ia32.h +++ b/src/ia32/simulator-ia32.h @@ -30,10 +30,21 @@ #include "allocation.h" +namespace v8 { +namespace internal { + // Since there is no simulator for the ia32 architecture the only thing we can // do is to call the entry directly. #define CALL_GENERATED_CODE(entry, p0, p1, p2, p3, p4) \ - entry(p0, p1, p2, p3, p4); + (entry(p0, p1, p2, p3, p4)) + +// Call the generated regexp code directly. The entry function pointer should +// expect seven int/pointer sized arguments and return an int. +#define CALL_GENERATED_REGEXP_CODE(entry, p0, p1, p2, p3, p4, p5, p6) \ + (entry(p0, p1, p2, p3, p4, p5, p6)) + +#define TRY_CATCH_FROM_ADDRESS(try_catch_address) \ + (reinterpret_cast(try_catch_address)) // The stack limit beyond which we will throw stack overflow errors in // generated code. Because generated code on ia32 uses the C stack, we @@ -51,12 +62,6 @@ class SimulatorStack : public v8::internal::AllStatic { static inline void UnregisterCTryCatch() { } }; -// Call the generated regexp code directly. The entry function pointer should -// expect eight int/pointer sized arguments and return an int. -#define CALL_GENERATED_REGEXP_CODE(entry, p0, p1, p2, p3, p4, p5, p6) \ - entry(p0, p1, p2, p3, p4, p5, p6) - -#define TRY_CATCH_FROM_ADDRESS(try_catch_address) \ - reinterpret_cast(try_catch_address) +} } // namespace v8::internal #endif // V8_IA32_SIMULATOR_IA32_H_ diff --git a/src/top.cc b/src/top.cc index 9a8ab2e32e..6ba45abb2a 100644 --- a/src/top.cc +++ b/src/top.cc @@ -66,6 +66,9 @@ v8::TryCatch* ThreadLocalTop::TryCatchHandler() { void ThreadLocalTop::Initialize() { c_entry_fp_ = 0; handler_ = 0; +#ifdef USE_SIMULATOR + simulator_ = assembler::arm::Simulator::current(); +#endif // USE_SIMULATOR #ifdef ENABLE_LOGGING_AND_PROFILING js_entry_sp_ = 0; #endif @@ -1060,6 +1063,11 @@ char* Top::ArchiveThread(char* to) { char* Top::RestoreThread(char* from) { memcpy(reinterpret_cast(&thread_local_), from, sizeof(thread_local_)); + // This might be just paranoia, but it seems to be needed in case a + // thread_local_ is restored on a separate OS thread. +#ifdef USE_SIMULATOR + thread_local_.simulator_ = assembler::arm::Simulator::current(); +#endif return from + sizeof(thread_local_); } diff --git a/src/top.h b/src/top.h index 5ee6424bea..e97289f359 100644 --- a/src/top.h +++ b/src/top.h @@ -29,6 +29,7 @@ #define V8_TOP_H_ #include "frames-inl.h" +#include "simulator.h" namespace v8 { namespace internal { @@ -103,6 +104,10 @@ class ThreadLocalTop BASE_EMBEDDED { Address c_entry_fp_; // the frame pointer of the top c entry frame Address handler_; // try-blocks are chained through the stack +#ifdef USE_SIMULATOR + assembler::arm::Simulator* simulator_; +#endif // USE_SIMULATOR + #ifdef ENABLE_LOGGING_AND_PROFILING Address js_entry_sp_; // the stack pointer of the bottom js entry frame #endif diff --git a/src/v8.cc b/src/v8.cc index b30564a391..e492de8c76 100644 --- a/src/v8.cc +++ b/src/v8.cc @@ -68,7 +68,7 @@ bool V8::Initialize(Deserializer* des) { OS::Setup(); // Initialize other runtime facilities -#if (defined(USE_SIMULATOR) || !V8_HOST_ARCH_ARM) && V8_TARGET_ARCH_ARM +#if defined(USE_SIMULATOR) ::assembler::arm::Simulator::Initialize(); #endif diff --git a/src/x64/simulator-x64.h b/src/x64/simulator-x64.h index a0fc3cbf4f..e607c8b87d 100644 --- a/src/x64/simulator-x64.h +++ b/src/x64/simulator-x64.h @@ -30,11 +30,22 @@ #include "allocation.h" -// Since there is no simulator for the ia32 architecture the only thing we can +namespace v8 { +namespace internal { + +// Since there is no simulator for the x64 architecture the only thing we can // do is to call the entry directly. // TODO(X64): Don't pass p0, since it isn't used? #define CALL_GENERATED_CODE(entry, p0, p1, p2, p3, p4) \ - entry(p0, p1, p2, p3, p4); + (entry(p0, p1, p2, p3, p4)) + +// Call the generated regexp code directly. The entry function pointer should +// expect seven int/pointer sized arguments and return an int. +#define CALL_GENERATED_REGEXP_CODE(entry, p0, p1, p2, p3, p4, p5, p6) \ + (entry(p0, p1, p2, p3, p4, p5, p6)) + +#define TRY_CATCH_FROM_ADDRESS(try_catch_address) \ + (reinterpret_cast(try_catch_address)) // The stack limit beyond which we will throw stack overflow errors in // generated code. Because generated code on x64 uses the C stack, we @@ -52,12 +63,6 @@ class SimulatorStack : public v8::internal::AllStatic { static inline void UnregisterCTryCatch() { } }; -// Call the generated regexp code directly. The entry function pointer should -// expect eight int/pointer sized arguments and return an int. -#define CALL_GENERATED_REGEXP_CODE(entry, p0, p1, p2, p3, p4, p5, p6) \ - entry(p0, p1, p2, p3, p4, p5, p6) - -#define TRY_CATCH_FROM_ADDRESS(try_catch_address) \ - reinterpret_cast(try_catch_address) +} } // namespace v8::internal #endif // V8_X64_SIMULATOR_X64_H_