Miscellaneous profile-driven Isolate plumbing.

While doing this, it became clear that quite a few functions should not be
static and should better live in various classes as instance methods, but I'll
leave this for a later CL.

BUG=v8:2487

Review URL: https://codereview.chromium.org/12314152

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@13765 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
svenpanne@chromium.org 2013-02-27 14:45:59 +00:00
parent 2a3063a7c3
commit bfaf38d2fd
23 changed files with 74 additions and 51 deletions

View File

@ -3367,7 +3367,7 @@ bool v8::Object::SetHiddenValue(v8::Handle<v8::String> key,
i::HandleScope scope(isolate);
i::Handle<i::JSObject> self = Utils::OpenHandle(this);
i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
i::Handle<i::String> key_symbol = FACTORY->LookupSymbol(key_obj);
i::Handle<i::String> key_symbol = isolate->factory()->LookupSymbol(key_obj);
i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
i::Handle<i::Object> result =
i::JSObject::SetHiddenProperty(self, key_symbol, value_obj);

View File

@ -75,7 +75,7 @@ void Deoptimizer::DeoptimizeFunctionWithPreparedFunctionList(
for (int i = 0; i < deopt_data->DeoptCount(); i++) {
if (deopt_data->Pc(i)->value() == -1) continue;
Address call_address = code_start_address + deopt_data->Pc(i)->value();
Address deopt_entry = GetDeoptimizationEntry(i, LAZY);
Address deopt_entry = GetDeoptimizationEntry(isolate, i, LAZY);
// We need calls to have a predictable size in the unoptimized code, but
// this is optimized code, so we don't have to have a predictable size.
int call_size_in_bytes =

View File

@ -844,7 +844,8 @@ void LCodeGen::DeoptimizeIf(Condition cc, LEnvironment* environment) {
Deoptimizer::BailoutType bailout_type = info()->IsStub()
? Deoptimizer::LAZY
: Deoptimizer::EAGER;
Address entry = Deoptimizer::GetDeoptimizationEntry(id, bailout_type);
Address entry =
Deoptimizer::GetDeoptimizationEntry(isolate(), id, bailout_type);
if (entry == NULL) {
Abort("bailout was not prepared");
return;

View File

@ -882,7 +882,7 @@ bool Compiler::CompileLazy(CompilationInfo* info) {
if (info->IsOptimizing()) {
Handle<Code> code = info->code();
ASSERT(shared->scope_info() != ScopeInfo::Empty());
ASSERT(shared->scope_info() != ScopeInfo::Empty(isolate));
info->closure()->ReplaceCode(*code);
InsertCodeIntoOptimizedCodeMap(info);
return true;
@ -983,7 +983,7 @@ void Compiler::InstallOptimizedCode(OptimizingCompiler* optimizing_compiler) {
InstallCodeCommon(*info);
if (status == OptimizingCompiler::SUCCEEDED) {
Handle<Code> code = info->code();
ASSERT(info->shared_info()->scope_info() != ScopeInfo::Empty());
ASSERT(info->shared_info()->scope_info() != ScopeInfo::Empty(isolate));
info->closure()->ReplaceCode(*code);
if (info->shared_info()->SearchOptimizedCodeMap(
info->closure()->context()->native_context()) == -1) {
@ -1004,7 +1004,8 @@ Handle<SharedFunctionInfo> Compiler::BuildFunctionInfo(FunctionLiteral* literal,
info.SetScope(literal->scope());
info.SetLanguageMode(literal->scope()->language_mode());
LiveEditFunctionTracker live_edit_tracker(info.isolate(), literal);
Isolate* isolate = info.isolate();
LiveEditFunctionTracker live_edit_tracker(isolate, literal);
// Determine if the function can be lazily compiled. This is necessary to
// allow some of our builtin JS files to be lazily compiled. These
// builtins cannot be handled lazily by the parser, since we have to know
@ -1018,11 +1019,11 @@ Handle<SharedFunctionInfo> Compiler::BuildFunctionInfo(FunctionLiteral* literal,
bool allow_lazy = literal->AllowsLazyCompilation() &&
!DebuggerWantsEagerCompilation(&info, allow_lazy_without_ctx);
Handle<ScopeInfo> scope_info(ScopeInfo::Empty());
Handle<ScopeInfo> scope_info(ScopeInfo::Empty(isolate));
// Generate code
if (FLAG_lazy && allow_lazy && !literal->is_parenthesized()) {
Handle<Code> code = info.isolate()->builtins()->LazyCompile();
Handle<Code> code = isolate->builtins()->LazyCompile();
info.SetCode(code);
} else if (GenerateCode(&info)) {
ASSERT(!info.code().is_null());

View File

@ -268,19 +268,19 @@ Handle<Value> Shell::Write(const Arguments& args) {
Exit(1);
}
}
return Undefined();
return Undefined(args.GetIsolate());
}
Handle<Value> Shell::EnableProfiler(const Arguments& args) {
V8::ResumeProfiler();
return Undefined();
return Undefined(args.GetIsolate());
}
Handle<Value> Shell::DisableProfiler(const Arguments& args) {
V8::PauseProfiler();
return Undefined();
return Undefined(args.GetIsolate());
}
@ -342,7 +342,7 @@ Handle<Value> Shell::Load(const Arguments& args) {
return Throw("Error executing file");
}
}
return Undefined();
return Undefined(args.GetIsolate());
}
static int32_t convertToInt(Local<Value> value_in, TryCatch* try_catch) {
@ -407,7 +407,9 @@ Handle<Value> Shell::CreateExternalArrayBuffer(Isolate* isolate,
buffer->SetIndexedPropertiesToExternalArrayData(
data, v8::kExternalByteArray, length);
buffer->Set(Symbols::byteLength(isolate), Int32::New(length), ReadOnly);
buffer->Set(Symbols::byteLength(isolate),
Int32::New(length, isolate),
ReadOnly);
return buffer;
}
@ -451,12 +453,21 @@ Handle<Object> Shell::CreateExternalArray(Isolate* isolate,
array->SetIndexedPropertiesToExternalArrayData(
static_cast<uint8_t*>(data) + byteOffset, type, length);
array->SetHiddenValue(Symbols::ArrayMarkerPropName(isolate),
Int32::New(type));
array->Set(Symbols::byteLength(isolate), Int32::New(byteLength), ReadOnly);
array->Set(Symbols::byteOffset(isolate), Int32::New(byteOffset), ReadOnly);
array->Set(Symbols::length(isolate), Int32::New(length), ReadOnly);
array->Set(Symbols::BYTES_PER_ELEMENT(isolate), Int32::New(element_size));
array->Set(Symbols::buffer(isolate), buffer, ReadOnly);
Int32::New(type, isolate));
array->Set(Symbols::byteLength(isolate),
Int32::New(byteLength, isolate),
ReadOnly);
array->Set(Symbols::byteOffset(isolate),
Int32::New(byteOffset, isolate),
ReadOnly);
array->Set(Symbols::length(isolate),
Int32::New(length, isolate),
ReadOnly);
array->Set(Symbols::BYTES_PER_ELEMENT(isolate),
Int32::New(element_size, isolate));
array->Set(Symbols::buffer(isolate),
buffer,
ReadOnly);
return array;
}
@ -549,7 +560,7 @@ Handle<Value> Shell::CreateExternalArray(const Arguments& args,
Handle<Object> global = Context::GetCurrent()->Global();
Handle<Value> array_buffer = global->Get(Symbols::ArrayBuffer(isolate));
ASSERT(!try_catch.HasCaught() && array_buffer->IsFunction());
Handle<Value> buffer_args[] = { Uint32::New(byteLength) };
Handle<Value> buffer_args[] = { Uint32::New(byteLength, isolate) };
Handle<Value> result = Handle<Function>::Cast(array_buffer)->NewInstance(
1, buffer_args);
if (try_catch.HasCaught()) return result;
@ -614,7 +625,7 @@ Handle<Value> Shell::ArrayBufferSlice(const Arguments& args) {
}
Local<Function> constructor = Local<Function>::Cast(self->GetConstructor());
Handle<Value> new_args[] = { Uint32::New(end - begin) };
Handle<Value> new_args[] = { Uint32::New(end - begin, isolate) };
Handle<Value> result = constructor->NewInstance(1, new_args);
if (try_catch.HasCaught()) return result;
Handle<Object> buffer = result->ToObject();
@ -681,7 +692,7 @@ Handle<Value> Shell::ArraySubArray(const Arguments& args) {
Local<Function> constructor = Local<Function>::Cast(self->GetConstructor());
Handle<Value> construct_args[] = {
buffer, Uint32::New(byteOffset), Uint32::New(length)
buffer, Uint32::New(byteOffset, isolate), Uint32::New(length, isolate)
};
return constructor->NewInstance(3, construct_args);
}
@ -823,7 +834,7 @@ Handle<Value> Shell::ArraySet(const Arguments& args) {
}
}
return Undefined();
return Undefined(args.GetIsolate());
}
@ -889,7 +900,7 @@ Handle<Value> Shell::Uint8ClampedArray(const Arguments& args) {
Handle<Value> Shell::Yield(const Arguments& args) {
v8::Unlocker unlocker(args.GetIsolate());
return Undefined();
return Undefined(args.GetIsolate());
}
@ -897,7 +908,7 @@ Handle<Value> Shell::Quit(const Arguments& args) {
int exit_code = args[0]->Int32Value();
OnExit();
exit(exit_code);
return Undefined();
return Undefined(args.GetIsolate());
}
@ -1100,8 +1111,8 @@ void Shell::InstallUtilityScript(Isolate* isolate) {
HandleScope scope;
// If we use the utility context, we have to set the security tokens so that
// utility, evaluation and debug context can all access each other.
utility_context_->SetSecurityToken(Undefined());
evaluation_context_->SetSecurityToken(Undefined());
utility_context_->SetSecurityToken(Undefined(isolate));
evaluation_context_->SetSecurityToken(Undefined(isolate));
Context::Scope utility_scope(utility_context_);
#ifdef ENABLE_DEBUGGER_SUPPORT
@ -1454,7 +1465,7 @@ Handle<Value> Shell::ReadBuffer(const Arguments& args) {
buffer->SetIndexedPropertiesToExternalArrayData(
data, kExternalUnsignedByteArray, length);
buffer->Set(Symbols::byteLength(isolate),
Int32::New(static_cast<int32_t>(length)), ReadOnly);
Int32::New(static_cast<int32_t>(length), isolate), ReadOnly);
return buffer;
}

View File

@ -634,18 +634,19 @@ void Deoptimizer::DeleteFrameDescriptions() {
}
Address Deoptimizer::GetDeoptimizationEntry(int id,
Address Deoptimizer::GetDeoptimizationEntry(Isolate* isolate,
int id,
BailoutType type,
GetEntryMode mode) {
ASSERT(id >= 0);
if (id >= kMaxNumberOfEntries) return NULL;
MemoryChunk* base = NULL;
if (mode == ENSURE_ENTRY_CODE) {
EnsureCodeForDeoptimizationEntry(type, id);
EnsureCodeForDeoptimizationEntry(isolate, type, id);
} else {
ASSERT(mode == CALCULATE_ENTRY_ADDRESS);
}
DeoptimizerData* data = Isolate::Current()->deoptimizer_data();
DeoptimizerData* data = isolate->deoptimizer_data();
if (type == EAGER) {
base = data->eager_deoptimization_entry_code_;
} else {
@ -1572,14 +1573,15 @@ void Deoptimizer::AddDoubleValue(intptr_t slot_address, double value) {
}
void Deoptimizer::EnsureCodeForDeoptimizationEntry(BailoutType type,
void Deoptimizer::EnsureCodeForDeoptimizationEntry(Isolate* isolate,
BailoutType type,
int max_entry_id) {
// We cannot run this if the serializer is enabled because this will
// cause us to emit relocation information for the external
// references. This is fine because the deoptimizer's code section
// isn't meant to be serialized at all.
ASSERT(type == EAGER || type == LAZY);
DeoptimizerData* data = Isolate::Current()->deoptimizer_data();
DeoptimizerData* data = isolate->deoptimizer_data();
int entry_count = (type == EAGER)
? data->eager_deoptimization_entry_code_entries_
: data->lazy_deoptimization_entry_code_entries_;
@ -1588,7 +1590,7 @@ void Deoptimizer::EnsureCodeForDeoptimizationEntry(BailoutType type,
while (max_entry_id >= entry_count) entry_count *= 2;
ASSERT(entry_count <= Deoptimizer::kMaxNumberOfEntries);
MacroAssembler masm(Isolate::Current(), NULL, 16 * KB);
MacroAssembler masm(isolate, NULL, 16 * KB);
masm.set_emit_debug_code(false);
GenerateDeoptimizationEntries(&masm, entry_count, type);
CodeDesc desc;

View File

@ -255,6 +255,7 @@ class Deoptimizer : public Malloced {
static Address GetDeoptimizationEntry(
Isolate* isolate,
int id,
BailoutType type,
GetEntryMode mode = ENSURE_ENTRY_CODE);
@ -316,7 +317,8 @@ class Deoptimizer : public Malloced {
static size_t GetMaxDeoptTableSize();
static void EnsureCodeForDeoptimizationEntry(BailoutType type,
static void EnsureCodeForDeoptimizationEntry(Isolate* isolate,
BailoutType type,
int max_entry_id);
private:

View File

@ -1087,7 +1087,7 @@ void JavaScriptFrame::Print(StringStream* accumulator,
// doesn't contain scope info, scope_info will return 0 for the number of
// parameters, stack local variables, context local variables, stack slots,
// or context slots.
Handle<ScopeInfo> scope_info(ScopeInfo::Empty());
Handle<ScopeInfo> scope_info(ScopeInfo::Empty(isolate()));
if (function->IsJSFunction()) {
Handle<SharedFunctionInfo> shared(JSFunction::cast(function)->shared());

View File

@ -3271,7 +3271,7 @@ MaybeObject* Heap::AllocateSharedFunctionInfo(Object* name) {
Code* illegal = isolate_->builtins()->builtin(Builtins::kIllegal);
share->set_code(illegal);
share->ClearOptimizedCodeMap();
share->set_scope_info(ScopeInfo::Empty());
share->set_scope_info(ScopeInfo::Empty(isolate_));
Code* construct_stub =
isolate_->builtins()->builtin(Builtins::kJSConstructStubGeneric);
share->set_construct_stub(construct_stub);

View File

@ -7625,7 +7625,7 @@ bool HOptimizedGraphBuilder::TryInline(CallKind call_kind,
TraceInline(target, caller, "could not generate deoptimization info");
return false;
}
if (target_shared->scope_info() == ScopeInfo::Empty()) {
if (target_shared->scope_info() == ScopeInfo::Empty(isolate())) {
// The scope info might not have been set if a lazily compiled
// function is inlined before being called for the first time.
Handle<ScopeInfo> target_scope_info =

View File

@ -157,7 +157,7 @@ void Deoptimizer::DeoptimizeFunctionWithPreparedFunctionList(
// Patch lazy deoptimization entry.
Address call_address = code_start_address + deopt_data->Pc(i)->value();
CodePatcher patcher(call_address, patch_size());
Address deopt_entry = GetDeoptimizationEntry(i, LAZY);
Address deopt_entry = GetDeoptimizationEntry(isolate, i, LAZY);
patcher.masm()->call(deopt_entry, RelocInfo::NONE32);
// We use RUNTIME_ENTRY for deoptimization bailouts.
RelocInfo rinfo(call_address + 1, // 1 after the call opcode.

View File

@ -845,7 +845,8 @@ void LCodeGen::DeoptimizeIf(Condition cc, LEnvironment* environment) {
Deoptimizer::BailoutType bailout_type = info()->IsStub()
? Deoptimizer::LAZY
: Deoptimizer::EAGER;
Address entry = Deoptimizer::GetDeoptimizationEntry(id, bailout_type);
Address entry =
Deoptimizer::GetDeoptimizationEntry(isolate(), id, bailout_type);
if (entry == NULL) {
Abort("bailout was not prepared");
return;

View File

@ -2148,6 +2148,7 @@ bool Isolate::Init(Deserializer* des) {
// the snapshot.
HandleScope scope(this);
Deoptimizer::EnsureCodeForDeoptimizationEntry(
this,
Deoptimizer::LAZY,
kDeoptTableSerializeEntryCount - 1);
}

View File

@ -3935,7 +3935,7 @@ void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) {
CEntryStub::GenerateAheadOfTime(isolate);
WriteInt32ToHeapNumberStub::GenerateFixedRegStubsAheadOfTime(isolate);
StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime(isolate);
RecordWriteStub::GenerateFixedRegStubsAheadOfTime();
RecordWriteStub::GenerateFixedRegStubsAheadOfTime(isolate);
}

View File

@ -73,7 +73,7 @@ void Deoptimizer::DeoptimizeFunctionWithPreparedFunctionList(
for (int i = 0; i < deopt_data->DeoptCount(); i++) {
if (deopt_data->Pc(i)->value() == -1) continue;
Address call_address = code_start_address + deopt_data->Pc(i)->value();
Address deopt_entry = GetDeoptimizationEntry(i, LAZY);
Address deopt_entry = GetDeoptimizationEntry(isolate, i, LAZY);
int call_size_in_bytes = MacroAssembler::CallSize(deopt_entry,
RelocInfo::NONE32);
int call_size_in_words = call_size_in_bytes / Assembler::kInstrSize;

View File

@ -809,7 +809,8 @@ void LCodeGen::DeoptimizeIf(Condition cc,
Deoptimizer::BailoutType bailout_type = info()->IsStub()
? Deoptimizer::LAZY
: Deoptimizer::EAGER;
Address entry = Deoptimizer::GetDeoptimizationEntry(id, bailout_type);
Address entry =
Deoptimizer::GetDeoptimizationEntry(isolate(), id, bailout_type);
if (entry == NULL) {
Abort("bailout was not prepared");
return;

View File

@ -3569,7 +3569,7 @@ class ScopeInfo : public FixedArray {
static Handle<ScopeInfo> Create(Scope* scope, Zone* zone);
// Serializes empty scope info.
static ScopeInfo* Empty();
static ScopeInfo* Empty(Isolate* isolate);
#ifdef DEBUG
void Print();

View File

@ -10367,7 +10367,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameDetails) {
Handle<JSFunction> function(JSFunction::cast(frame_inspector.GetFunction()));
Handle<SharedFunctionInfo> shared(function->shared());
Handle<ScopeInfo> scope_info(shared->scope_info());
ASSERT(*scope_info != ScopeInfo::Empty());
ASSERT(*scope_info != ScopeInfo::Empty(isolate));
// Get the locals names and values into a temporary array.
//

View File

@ -149,8 +149,8 @@ Handle<ScopeInfo> ScopeInfo::Create(Scope* scope, Zone* zone) {
}
ScopeInfo* ScopeInfo::Empty() {
return reinterpret_cast<ScopeInfo*>(HEAP->empty_fixed_array());
ScopeInfo* ScopeInfo::Empty(Isolate* isolate) {
return reinterpret_cast<ScopeInfo*>(isolate->heap()->empty_fixed_array());
}

View File

@ -105,7 +105,7 @@ Variable* VariableMap::Lookup(Handle<String> name) {
// Implementation of Scope
Scope::Scope(Scope* outer_scope, ScopeType type, Zone* zone)
: isolate_(Isolate::Current()),
: isolate_(zone->isolate()),
inner_scopes_(4, zone),
variables_(zone),
internals_(4, zone),

View File

@ -547,9 +547,10 @@ void ExternalReferenceTable::PopulateTable(Isolate* isolate) {
// Add a small set of deopt entry addresses to encoder without generating the
// deopt table code, which isn't possible at deserialization time.
HandleScope scope(Isolate::Current());
HandleScope scope(isolate);
for (int entry = 0; entry < kDeoptTableSerializeEntryCount; ++entry) {
Address address = Deoptimizer::GetDeoptimizationEntry(
isolate,
entry,
Deoptimizer::LAZY,
Deoptimizer::CALCULATE_ENTRY_ADDRESS);

View File

@ -85,7 +85,8 @@ void Deoptimizer::DeoptimizeFunctionWithPreparedFunctionList(
// There is room enough to write a long call instruction because we pad
// LLazyBailout instructions with nops if necessary.
CodePatcher patcher(call_address, Assembler::kCallInstructionLength);
patcher.masm()->Call(GetDeoptimizationEntry(i, LAZY), RelocInfo::NONE64);
patcher.masm()->Call(GetDeoptimizationEntry(isolate, i, LAZY),
RelocInfo::NONE64);
ASSERT(prev_call_address == NULL ||
call_address >= prev_call_address + patch_size());
ASSERT(call_address + patch_size() <= code->instruction_end());

View File

@ -732,7 +732,8 @@ void LCodeGen::DeoptimizeIf(Condition cc, LEnvironment* environment) {
Deoptimizer::BailoutType bailout_type = info()->IsStub()
? Deoptimizer::LAZY
: Deoptimizer::EAGER;
Address entry = Deoptimizer::GetDeoptimizationEntry(id, bailout_type);
Address entry =
Deoptimizer::GetDeoptimizationEntry(isolate(), id, bailout_type);
if (entry == NULL) {
Abort("bailout was not prepared");
return;