#define LOG_API(isolate, expr) LOG(isolate, ApiEntryCall(expr))
-#define ENTER_V8(isolate) \
- ASSERT((isolate)->IsInitialized()); \
- i::VMState __state__((isolate), i::OTHER)
-#define LEAVE_V8(isolate) \
- i::VMState __state__((isolate), i::EXTERNAL)
+#define ENTER_V8(isolate) \
+ ASSERT((isolate)->IsInitialized()); \
+ i::VMState<i::OTHER> __state__((isolate))
namespace v8 {
const char* message) {
i::Isolate* isolate = i::Isolate::Current();
if (isolate->IsInitialized()) {
- i::VMState __state__(isolate, i::OTHER);
+ i::VMState<i::OTHER> state(isolate);
API_Fatal(location, message);
} else {
API_Fatal(location, message);
i::V8::SetFatalError();
FatalErrorCallback callback = GetFatalErrorHandler();
const char* message = "Allocation failed - process out of memory";
- {
- if (isolate->IsInitialized()) {
- LEAVE_V8(isolate);
- callback(location, message);
- } else {
- callback(location, message);
- }
- }
+ callback(location, message);
// If the callback returns, we stop execution.
UNREACHABLE();
}
if (FLAG_log_timer_events) {
FrameScope frame(this, StackFrame::MANUAL);
PushSafepointRegisters();
- PrepareCallCFunction(0, r0);
- CallCFunction(ExternalReference::log_enter_external_function(isolate()), 0);
+ PrepareCallCFunction(1, r0);
+ mov(r0, Operand(ExternalReference::isolate_address(isolate())));
+ CallCFunction(ExternalReference::log_enter_external_function(isolate()), 1);
PopSafepointRegisters();
}
if (FLAG_log_timer_events) {
FrameScope frame(this, StackFrame::MANUAL);
PushSafepointRegisters();
- PrepareCallCFunction(0, r0);
- CallCFunction(ExternalReference::log_leave_external_function(isolate()), 0);
+ PrepareCallCFunction(1, r0);
+ mov(r0, Operand(ExternalReference::isolate_address(isolate())));
+ CallCFunction(ExternalReference::log_leave_external_function(isolate()), 1);
PopSafepointRegisters();
}
v8::Handle<v8::Value> value;
{
// Leaving JavaScript.
- VMState state(isolate, EXTERNAL);
+ VMState<EXTERNAL> state(isolate);
ExternalCallbackScope call_scope(isolate,
v8::ToCData<Address>(callback_obj));
value = callback(new_args);
v8::Handle<v8::Value> value;
{
// Leaving JavaScript.
- VMState state(isolate, EXTERNAL);
+ VMState<EXTERNAL> state(isolate);
ExternalCallbackScope call_scope(isolate,
v8::ToCData<Address>(callback_obj));
value = callback(new_args);
isolate->counters()->total_compile_size()->Increment(source_length);
// The VM is in the COMPILER state until exiting this function.
- VMState state(isolate, COMPILER);
+ VMState<COMPILER> state(isolate);
CompilationCache* compilation_cache = isolate->compilation_cache();
isolate->counters()->total_compile_size()->Increment(source_length);
// The VM is in the COMPILER state until exiting this function.
- VMState state(isolate, COMPILER);
+ VMState<COMPILER> state(isolate);
// Do a lookup in the compilation cache; if the entry is not there, invoke
// the compiler and add the result to the cache.
ZoneScope zone_scope(info->zone(), DELETE_ON_EXIT);
// The VM is in the COMPILER state until exiting this function.
- VMState state(isolate, COMPILER);
+ VMState<COMPILER> state(isolate);
PostponeInterruptsScope postpone(isolate);
}
SmartPointer<CompilationInfo> info(new CompilationInfoWithZone(closure));
- VMState state(isolate, PARALLEL_COMPILER);
+ VMState<COMPILER> state(isolate);
PostponeInterruptsScope postpone(isolate);
Handle<SharedFunctionInfo> shared = info->shared_info();
}
Isolate* isolate = info->isolate();
- VMState state(isolate, PARALLEL_COMPILER);
+ VMState<COMPILER> state(isolate);
Logger::TimerEventScope timer(
isolate, Logger::TimerEventScope::v8_recompile_synchronous);
// If crankshaft succeeded, install the optimized code else install
Isolate* isolate = function->GetIsolate();
// Entering JavaScript.
- VMState state(isolate, JS);
+ VMState<JS> state(isolate);
// Placeholder for return value.
MaybeObject* value = reinterpret_cast<Object*>(kZapValue);
DEFINE_bool(trace_isolates, false, "trace isolate state changes")
-// VM state
-DEFINE_bool(log_state_changes, false, "Log state changes.")
-
// Regexp
DEFINE_bool(regexp_possessive_quantifier,
false,
DEFINE_bool(log_timer_events, false,
"Time events including external callbacks.")
DEFINE_implication(log_timer_events, log_internal_timer_events)
+DEFINE_implication(log_internal_timer_events, prof)
//
// Disassembler only flags
ASSERT(!object_->IsExternalTwoByteString() ||
ExternalTwoByteString::cast(object_)->resource() != NULL);
// Leaving V8.
- VMState state(isolate, EXTERNAL);
+ VMState<EXTERNAL> state(isolate);
if (near_death_callback_ != NULL) {
if (IsWeakCallback::decode(flags_)) {
WeakReferenceCallback callback =
LOG(isolate, ApiObjectAccess("interceptor-named-enum", *object));
{
// Leaving JavaScript.
- VMState state(isolate, EXTERNAL);
+ VMState<EXTERNAL> state(isolate);
result = enum_fun(info);
}
}
LOG(isolate, ApiObjectAccess("interceptor-indexed-enum", *object));
{
// Leaving JavaScript.
- VMState state(isolate, EXTERNAL);
+ VMState<EXTERNAL> state(isolate);
result = enum_fun(info);
#if ENABLE_EXTRA_CHECKS
CHECK(result.IsEmpty() || v8::Utils::OpenHandle(*result)->IsJSObject());
const char* gc_reason,
const char* collector_reason) {
// The VM is in the GC state until exiting this function.
- VMState state(isolate_, GC);
+ VMState<GC> state(isolate_);
#ifdef DEBUG
// Reset the allocation timeout to the GC interval, but make sure to
{
GCTracer::Scope scope(tracer, GCTracer::Scope::EXTERNAL);
- VMState state(isolate_, EXTERNAL);
+ VMState<EXTERNAL> state(isolate_);
CallGCPrologueCallbacks(gc_type);
}
{
GCTracer::Scope scope(tracer, GCTracer::Scope::EXTERNAL);
- VMState state(isolate_, EXTERNAL);
+ VMState<EXTERNAL> state(isolate_);
CallGCEpilogueCallbacks(gc_type);
}
if (FLAG_log_timer_events) {
FrameScope frame(this, StackFrame::MANUAL);
PushSafepointRegisters();
- PrepareCallCFunction(0, eax);
- CallCFunction(ExternalReference::log_enter_external_function(isolate()), 0);
+ PrepareCallCFunction(1, eax);
+ mov(Operand(esp, 0),
+ Immediate(ExternalReference::isolate_address(isolate())));
+ CallCFunction(ExternalReference::log_enter_external_function(isolate()), 1);
PopSafepointRegisters();
}
if (FLAG_log_timer_events) {
FrameScope frame(this, StackFrame::MANUAL);
PushSafepointRegisters();
- PrepareCallCFunction(0, eax);
- CallCFunction(ExternalReference::log_leave_external_function(isolate()), 0);
+ PrepareCallCFunction(1, eax);
+ mov(Operand(esp, 0),
+ Immediate(ExternalReference::isolate_address(isolate())));
+ CallCFunction(ExternalReference::log_leave_external_function(isolate()), 1);
PopSafepointRegisters();
}
HandleScope scope(this);
Handle<JSObject> receiver_handle(receiver);
Handle<Object> data(AccessCheckInfo::cast(data_obj)->data(), this);
- { VMState state(this, EXTERNAL);
+ { VMState<EXTERNAL> state(this);
thread_local_top()->failed_access_check_callback_(
v8::Utils::ToLocal(receiver_handle),
type,
bool result = false;
{
// Leaving JavaScript.
- VMState state(this, EXTERNAL);
+ VMState<EXTERNAL> state(this);
result = callback(v8::Utils::ToLocal(receiver_handle),
v8::Utils::ToLocal(key_handle),
type,
bool result = false;
{
// Leaving JavaScript.
- VMState state(this, EXTERNAL);
+ VMState<EXTERNAL> state(this);
result = callback(v8::Utils::ToLocal(receiver_handle),
index,
type,
heap_profiler_ = new HeapProfiler(heap());
// Enable logging before setting up the heap
- logger_->SetUp();
+ logger_->SetUp(this);
// Initialize other runtime facilities
#if defined(USE_SIMULATOR)
class ThreadManager;
class ThreadState;
class ThreadVisitor; // Defined in v8threads.h
-class VMState;
+template <StateTag Tag> class VMState;
// 'void function pointer', used to roundtrip the
// ExternalReference::ExternalReferenceRedirector since we can not include
return thread_local_top_.current_vm_state_;
}
- void SetCurrentVMState(StateTag state) {
+ void set_current_vm_state(StateTag state) {
thread_local_top_.current_vm_state_ = state;
}
FLAG_prof_auto = false;
}
- bool open_log_file = FLAG_log || FLAG_log_runtime || FLAG_log_api
- || FLAG_log_code || FLAG_log_gc || FLAG_log_handles || FLAG_log_suspect
- || FLAG_log_regexp || FLAG_log_state_changes || FLAG_ll_prof
- || FLAG_log_internal_timer_events;
-
// If we're logging anything, we need to open the log file.
- if (open_log_file) {
+ if (Log::InitLogAtStart()) {
if (strcmp(FLAG_logfile, "-") == 0) {
OpenStdout();
} else if (strcmp(FLAG_logfile, kLogToTemporaryFile) == 0) {
// Disables logging, but preserves acquired resources.
void stop() { is_stopped_ = true; }
+ static bool InitLogAtStart() {
+ return FLAG_log || FLAG_log_runtime || FLAG_log_api
+ || FLAG_log_code || FLAG_log_gc || FLAG_log_handles || FLAG_log_suspect
+ || FLAG_log_regexp || FLAG_ll_prof || FLAG_log_internal_timer_events;
+ }
+
// Frees all resources acquired in Initialize and Open... functions.
// When a temporary file is used for the log, returns its stream descriptor,
// leaving the file open.
}
-void Logger::EnterExternal() {
- LOG(ISOLATE, TimerEvent(START, TimerEventScope::v8_external));
+void Logger::EnterExternal(Isolate* isolate) {
+ LOG(isolate, TimerEvent(START, TimerEventScope::v8_external));
+ ASSERT(isolate->current_vm_state() == JS);
+ isolate->set_current_vm_state(EXTERNAL);
}
-void Logger::LeaveExternal() {
- LOG(ISOLATE, TimerEvent(END, TimerEventScope::v8_external));
+void Logger::LeaveExternal(Isolate* isolate) {
+ LOG(isolate, TimerEvent(END, TimerEventScope::v8_external));
+ ASSERT(isolate->current_vm_state() == EXTERNAL);
+ isolate->set_current_vm_state(JS);
}
}
-bool Logger::SetUp() {
+bool Logger::SetUp(Isolate* isolate) {
// Tests and EnsureInitialize() can call this twice in a row. It's harmless.
if (is_initialized_) return true;
is_initialized_ = true;
FLAG_prof_auto = false;
}
- // TODO(isolates): this assert introduces cyclic dependency (logger
- // -> thread local top -> heap -> logger).
- // ASSERT(VMState::is_outermost_external());
-
log_->Initialize();
if (FLAG_ll_prof) LogCodeInfo();
- Isolate* isolate = Isolate::Current();
ticker_ = new Ticker(isolate, kSamplingIntervalMs);
- bool start_logging = FLAG_log || FLAG_log_runtime || FLAG_log_api
- || FLAG_log_code || FLAG_log_gc || FLAG_log_handles || FLAG_log_suspect
- || FLAG_log_regexp || FLAG_log_state_changes || FLAG_ll_prof
- || FLAG_log_internal_timer_events;
-
- if (start_logging) {
+ if (Log::InitLogAtStart()) {
logging_nesting_ = 1;
}
#undef DECLARE_ENUM
// Acquires resources for logging if the right flags are set.
- bool SetUp();
+ bool SetUp(Isolate* isolate);
// Sets the current code event handler.
void SetCodeEventHandler(uint32_t options,
void TimerEvent(StartEnd se, const char* name);
- static void EnterExternal();
- static void LeaveExternal();
+ static void EnterExternal(Isolate* isolate);
+ static void LeaveExternal(Isolate* isolate);
class TimerEventScope {
public:
friend class LogMessageBuilder;
friend class TimeLog;
friend class Profiler;
- friend class VMState;
+ template <StateTag Tag> friend class VMState;
friend class LoggerTestHelper;
v8::Handle<v8::Value> result;
{
// Leaving JavaScript.
- VMState state(isolate, EXTERNAL);
+ VMState<EXTERNAL> state(isolate);
result = call_fun(v8::Utils::ToLocal(key), info);
}
RETURN_IF_SCHEDULED_EXCEPTION(isolate);
v8::Handle<v8::Value> result;
{
// Leaving JavaScript.
- VMState state(isolate, EXTERNAL);
+ VMState<EXTERNAL> state(isolate);
Handle<Object> value_unhole(value->IsTheHole() ?
isolate->heap()->undefined_value() :
value,
v8::AccessorInfo info(args.end());
{
// Leaving JavaScript.
- VMState state(isolate, EXTERNAL);
+ VMState<EXTERNAL> state(isolate);
call_fun(v8::Utils::ToLocal(key),
v8::Utils::ToLocal(value_handle),
info);
v8::Handle<v8::Integer> result;
{
// Leaving JavaScript.
- VMState state(isolate, EXTERNAL);
+ VMState<EXTERNAL> state(isolate);
result = query(v8::Utils::ToLocal(name_handle), info);
}
if (!result.IsEmpty()) {
v8::Handle<v8::Value> result;
{
// Leaving JavaScript.
- VMState state(isolate, EXTERNAL);
+ VMState<EXTERNAL> state(isolate);
result = getter(v8::Utils::ToLocal(name_handle), info);
}
if (!result.IsEmpty()) return DONT_ENUM;
v8::Handle<v8::Integer> result;
{
// Leaving JavaScript.
- VMState state(isolate, EXTERNAL);
+ VMState<EXTERNAL> state(isolate);
result = query(index, info);
}
if (!result.IsEmpty())
v8::Handle<v8::Value> result;
{
// Leaving JavaScript.
- VMState state(isolate, EXTERNAL);
+ VMState<EXTERNAL> state(isolate);
result = getter(index, info);
}
if (!result.IsEmpty()) return NONE;
v8::Handle<v8::Boolean> result;
{
// Leaving JavaScript.
- VMState state(isolate, EXTERNAL);
+ VMState<EXTERNAL> state(isolate);
result = deleter(v8::Utils::ToLocal(name_handle), info);
}
RETURN_IF_SCHEDULED_EXCEPTION(isolate);
v8::Handle<v8::Boolean> result;
{
// Leaving JavaScript.
- VMState state(isolate, EXTERNAL);
+ VMState<EXTERNAL> state(isolate);
result = deleter(index, info);
}
RETURN_IF_SCHEDULED_EXCEPTION(isolate);
v8::Handle<v8::Value> result;
{
// Leaving JavaScript.
- VMState state(isolate, EXTERNAL);
+ VMState<EXTERNAL> state(isolate);
result = setter(index, v8::Utils::ToLocal(value_handle), info);
}
RETURN_IF_SCHEDULED_EXCEPTION(isolate);
v8::Handle<v8::Value> result;
{
// Leaving JavaScript.
- VMState state(isolate, EXTERNAL);
+ VMState<EXTERNAL> state(isolate);
result = call_fun(v8::Utils::ToLocal(key), info);
}
RETURN_IF_SCHEDULED_EXCEPTION(isolate);
v8::AccessorInfo info(args.end());
{
// Leaving JavaScript.
- VMState state(isolate, EXTERNAL);
+ VMState<EXTERNAL> state(isolate);
call_fun(v8::Utils::ToLocal(key),
v8::Utils::ToLocal(value_handle),
info);
v8::Handle<v8::Value> result;
{
// Leaving JavaScript.
- VMState state(isolate, EXTERNAL);
+ VMState<EXTERNAL> state(isolate);
result = getter(index, info);
}
RETURN_IF_SCHEDULED_EXCEPTION(isolate);
v8::Handle<v8::Value> result;
{
// Leaving JavaScript.
- VMState state(isolate, EXTERNAL);
+ VMState<EXTERNAL> state(isolate);
result = getter(v8::Utils::ToLocal(name_handle), info);
}
RETURN_IF_SCHEDULED_EXCEPTION(isolate);
return gc_entry_;
case JS:
case COMPILER:
- case PARALLEL_COMPILER:
// DOM events handlers are reported as OTHER / EXTERNAL entries.
// To avoid confusing people, let's put all these entries into
// one bucket.
return false;
} else {
// Callback set. Let it decide if code generation is allowed.
- VMState state(isolate, EXTERNAL);
+ VMState<EXTERNAL> state(isolate);
return callback(v8::Utils::ToLocal(context));
}
}
v8::AccessorInfo info(custom_args.end());
{
// Leaving JavaScript.
- VMState state(isolate, EXTERNAL);
+ VMState<EXTERNAL> state(isolate);
ExternalCallbackScope call_scope(isolate, setter_address);
fun(v8::Utils::ToLocal(str), v8::Utils::ToLocal(value), info);
}
v8::Handle<v8::Value> r;
{
// Leaving JavaScript.
- VMState state(isolate, EXTERNAL);
+ VMState<EXTERNAL> state(isolate);
r = getter(v8::Utils::ToLocal(name), info);
}
RETURN_IF_SCHEDULED_EXCEPTION(isolate);
v8::Handle<v8::Value> r;
{
// Leaving JavaScript.
- VMState state(isolate, EXTERNAL);
+ VMState<EXTERNAL> state(isolate);
r = getter(v8::Utils::ToLocal(name), info);
}
RETURN_IF_SCHEDULED_EXCEPTION(isolate);
JS,
GC,
COMPILER,
- PARALLEL_COMPILER,
OTHER,
EXTERNAL
};
return "GC";
case COMPILER:
return "COMPILER";
- case PARALLEL_COMPILER:
- return "PARALLEL_COMPILER";
case OTHER:
return "OTHER";
case EXTERNAL:
}
-VMState::VMState(Isolate* isolate, StateTag tag)
+template <StateTag Tag>
+VMState<Tag>::VMState(Isolate* isolate)
: isolate_(isolate), previous_tag_(isolate->current_vm_state()) {
- if (FLAG_log_state_changes) {
- LOG(isolate, UncheckedStringEvent("Entering", StateToString(tag)));
- LOG(isolate, UncheckedStringEvent("From", StateToString(previous_tag_)));
- }
-
- if (FLAG_log_timer_events && previous_tag_ != EXTERNAL && tag == EXTERNAL) {
- LOG(isolate_, EnterExternal());
+ if (FLAG_log_timer_events && previous_tag_ != EXTERNAL && Tag == EXTERNAL) {
+ LOG(isolate_,
+ TimerEvent(Logger::START, Logger::TimerEventScope::v8_external));
}
-
- isolate_->SetCurrentVMState(tag);
+ isolate_->set_current_vm_state(Tag);
}
-VMState::~VMState() {
- if (FLAG_log_state_changes) {
+template <StateTag Tag>
+VMState<Tag>::~VMState() {
+ if (FLAG_log_timer_events && previous_tag_ != EXTERNAL && Tag == EXTERNAL) {
LOG(isolate_,
- UncheckedStringEvent("Leaving",
- StateToString(isolate_->current_vm_state())));
- LOG(isolate_,
- UncheckedStringEvent("To", StateToString(previous_tag_)));
- }
-
- if (FLAG_log_timer_events &&
- previous_tag_ != EXTERNAL && isolate_->current_vm_state() == EXTERNAL) {
- LOG(isolate_, LeaveExternal());
+ TimerEvent(Logger::END, Logger::TimerEventScope::v8_external));
}
-
- isolate_->SetCurrentVMState(previous_tag_);
+ isolate_->set_current_vm_state(previous_tag_);
}
namespace v8 {
namespace internal {
+template <StateTag Tag>
class VMState BASE_EMBEDDED {
public:
- inline VMState(Isolate* isolate, StateTag tag);
+ explicit inline VMState(Isolate* isolate);
inline ~VMState();
private:
if (FLAG_log_timer_events) {
FrameScope frame(this, StackFrame::MANUAL);
PushSafepointRegisters();
- PrepareCallCFunction(0);
- CallCFunction(ExternalReference::log_enter_external_function(isolate()), 0);
+ PrepareCallCFunction(1);
+ LoadAddress(arg_reg_1, ExternalReference::isolate_address(isolate()));
+ CallCFunction(ExternalReference::log_enter_external_function(isolate()), 1);
PopSafepointRegisters();
}
if (FLAG_log_timer_events) {
FrameScope frame(this, StackFrame::MANUAL);
PushSafepointRegisters();
- PrepareCallCFunction(0);
- CallCFunction(ExternalReference::log_leave_external_function(isolate()), 0);
+ PrepareCallCFunction(1);
+ LoadAddress(arg_reg_1, ExternalReference::isolate_address(isolate()));
+ CallCFunction(ExternalReference::log_leave_external_function(isolate()), 1);
PopSafepointRegisters();
}
JS: 0,
GC: 1,
COMPILER: 2,
- PARALLEL_COMPILER: 3,
- OTHER: 4,
- EXTERNAL: 5
+ OTHER: 3,
+ EXTERNAL: 4
};