Handlify the runtime lookup of CallIC and KeyedCallIC.
R=ulan@chromium.org BUG= TEST= Review URL: http://codereview.chromium.org/8345038 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@9701 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
acc0263755
commit
838fc27766
@ -527,7 +527,9 @@ MaybeObject* Accessors::FunctionGetLength(Object* object, void*) {
|
|||||||
// correctly yet. Compile it now and return the right length.
|
// correctly yet. Compile it now and return the right length.
|
||||||
HandleScope scope;
|
HandleScope scope;
|
||||||
Handle<JSFunction> handle(function);
|
Handle<JSFunction> handle(function);
|
||||||
if (!CompileLazy(handle, KEEP_EXCEPTION)) return Failure::Exception();
|
if (!JSFunction::CompileLazy(handle, KEEP_EXCEPTION)) {
|
||||||
|
return Failure::Exception();
|
||||||
|
}
|
||||||
return Smi::FromInt(handle->shared()->length());
|
return Smi::FromInt(handle->shared()->length());
|
||||||
} else {
|
} else {
|
||||||
return Smi::FromInt(function->shared()->length());
|
return Smi::FromInt(function->shared()->length());
|
||||||
|
13
src/api.cc
13
src/api.cc
@ -2794,7 +2794,7 @@ Local<Value> v8::Object::Get(uint32_t index) {
|
|||||||
ENTER_V8(isolate);
|
ENTER_V8(isolate);
|
||||||
i::Handle<i::JSObject> self = Utils::OpenHandle(this);
|
i::Handle<i::JSObject> self = Utils::OpenHandle(this);
|
||||||
EXCEPTION_PREAMBLE(isolate);
|
EXCEPTION_PREAMBLE(isolate);
|
||||||
i::Handle<i::Object> result = i::GetElement(self, index);
|
i::Handle<i::Object> result = i::Object::GetElement(self, index);
|
||||||
has_pending_exception = result.is_null();
|
has_pending_exception = result.is_null();
|
||||||
EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
|
EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
|
||||||
return Utils::ToLocal(result);
|
return Utils::ToLocal(result);
|
||||||
@ -3093,13 +3093,10 @@ static Local<Value> GetPropertyByLookup(i::Isolate* isolate,
|
|||||||
// If the property being looked up is a callback, it can throw
|
// If the property being looked up is a callback, it can throw
|
||||||
// an exception.
|
// an exception.
|
||||||
EXCEPTION_PREAMBLE(isolate);
|
EXCEPTION_PREAMBLE(isolate);
|
||||||
PropertyAttributes attributes;
|
PropertyAttributes ignored;
|
||||||
i::Handle<i::Object> result = i::Object::GetProperty(isolate,
|
i::Handle<i::Object> result =
|
||||||
receiver,
|
i::Object::GetProperty(receiver, receiver, lookup, name,
|
||||||
receiver,
|
&ignored);
|
||||||
lookup,
|
|
||||||
name,
|
|
||||||
&attributes);
|
|
||||||
has_pending_exception = result.is_null();
|
has_pending_exception = result.is_null();
|
||||||
EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
|
EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
|
||||||
|
|
||||||
|
@ -2007,7 +2007,9 @@ bool Genesis::InstallJSBuiltins(Handle<JSBuiltinsObject> builtins) {
|
|||||||
builtins->set_javascript_builtin(id, *function);
|
builtins->set_javascript_builtin(id, *function);
|
||||||
Handle<SharedFunctionInfo> shared
|
Handle<SharedFunctionInfo> shared
|
||||||
= Handle<SharedFunctionInfo>(function->shared());
|
= Handle<SharedFunctionInfo>(function->shared());
|
||||||
if (!EnsureCompiled(shared, CLEAR_EXCEPTION)) return false;
|
if (!SharedFunctionInfo::EnsureCompiled(shared, CLEAR_EXCEPTION)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
// Set the code object on the function object.
|
// Set the code object on the function object.
|
||||||
function->ReplaceCode(function->shared()->code());
|
function->ReplaceCode(function->shared()->code());
|
||||||
builtins->set_javascript_builtin_code(id, shared->code());
|
builtins->set_javascript_builtin_code(id, shared->code());
|
||||||
|
@ -1940,7 +1940,9 @@ bool Debug::EnsureDebugInfo(Handle<SharedFunctionInfo> shared) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Ensure shared in compiled. Return false if this failed.
|
// Ensure shared in compiled. Return false if this failed.
|
||||||
if (!EnsureCompiled(shared, CLEAR_EXCEPTION)) return false;
|
if (!SharedFunctionInfo::EnsureCompiled(shared, CLEAR_EXCEPTION)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Create the debug info object.
|
// Create the debug info object.
|
||||||
Handle<DebugInfo> debug_info = FACTORY->NewDebugInfo(shared);
|
Handle<DebugInfo> debug_info = FACTORY->NewDebugInfo(shared);
|
||||||
|
@ -376,13 +376,6 @@ Handle<Object> GetProperty(Handle<Object> obj,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Handle<Object> GetElement(Handle<Object> obj,
|
|
||||||
uint32_t index) {
|
|
||||||
Isolate* isolate = Isolate::Current();
|
|
||||||
CALL_HEAP_FUNCTION(isolate, Runtime::GetElement(obj, index), Object);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Handle<Object> GetPropertyWithInterceptor(Handle<JSObject> receiver,
|
Handle<Object> GetPropertyWithInterceptor(Handle<JSObject> receiver,
|
||||||
Handle<JSObject> holder,
|
Handle<JSObject> holder,
|
||||||
Handle<String> name,
|
Handle<String> name,
|
||||||
@ -888,53 +881,4 @@ Handle<ObjectHashTable> PutIntoObjectHashTable(Handle<ObjectHashTable> table,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool EnsureCompiled(Handle<SharedFunctionInfo> shared,
|
|
||||||
ClearExceptionFlag flag) {
|
|
||||||
return shared->is_compiled() || CompileLazyShared(shared, flag);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static bool CompileLazyHelper(CompilationInfo* info,
|
|
||||||
ClearExceptionFlag flag) {
|
|
||||||
// Compile the source information to a code object.
|
|
||||||
ASSERT(info->IsOptimizing() || !info->shared_info()->is_compiled());
|
|
||||||
ASSERT(!info->isolate()->has_pending_exception());
|
|
||||||
bool result = Compiler::CompileLazy(info);
|
|
||||||
ASSERT(result != Isolate::Current()->has_pending_exception());
|
|
||||||
if (!result && flag == CLEAR_EXCEPTION) {
|
|
||||||
info->isolate()->clear_pending_exception();
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool CompileLazyShared(Handle<SharedFunctionInfo> shared,
|
|
||||||
ClearExceptionFlag flag) {
|
|
||||||
CompilationInfo info(shared);
|
|
||||||
return CompileLazyHelper(&info, flag);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool CompileLazy(Handle<JSFunction> function, ClearExceptionFlag flag) {
|
|
||||||
bool result = true;
|
|
||||||
if (function->shared()->is_compiled()) {
|
|
||||||
function->ReplaceCode(function->shared()->code());
|
|
||||||
function->shared()->set_code_age(0);
|
|
||||||
} else {
|
|
||||||
CompilationInfo info(function);
|
|
||||||
result = CompileLazyHelper(&info, flag);
|
|
||||||
ASSERT(!result || function->is_compiled());
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool CompileOptimized(Handle<JSFunction> function,
|
|
||||||
int osr_ast_id,
|
|
||||||
ClearExceptionFlag flag) {
|
|
||||||
CompilationInfo info(function);
|
|
||||||
info.SetOptimizing(osr_ast_id);
|
|
||||||
return CompileLazyHelper(&info, flag);
|
|
||||||
}
|
|
||||||
|
|
||||||
} } // namespace v8::internal
|
} } // namespace v8::internal
|
||||||
|
@ -246,9 +246,6 @@ Handle<Object> GetProperty(Handle<JSReceiver> obj,
|
|||||||
Handle<Object> GetProperty(Handle<Object> obj,
|
Handle<Object> GetProperty(Handle<Object> obj,
|
||||||
Handle<Object> key);
|
Handle<Object> key);
|
||||||
|
|
||||||
Handle<Object> GetElement(Handle<Object> obj,
|
|
||||||
uint32_t index);
|
|
||||||
|
|
||||||
Handle<Object> GetPropertyWithInterceptor(Handle<JSObject> receiver,
|
Handle<Object> GetPropertyWithInterceptor(Handle<JSObject> receiver,
|
||||||
Handle<JSObject> holder,
|
Handle<JSObject> holder,
|
||||||
Handle<String> name,
|
Handle<String> name,
|
||||||
@ -345,22 +342,6 @@ Handle<ObjectHashTable> PutIntoObjectHashTable(Handle<ObjectHashTable> table,
|
|||||||
Handle<JSReceiver> key,
|
Handle<JSReceiver> key,
|
||||||
Handle<Object> value);
|
Handle<Object> value);
|
||||||
|
|
||||||
// Does lazy compilation of the given function. Returns true on success and
|
|
||||||
// false if the compilation resulted in a stack overflow.
|
|
||||||
enum ClearExceptionFlag { KEEP_EXCEPTION, CLEAR_EXCEPTION };
|
|
||||||
|
|
||||||
bool EnsureCompiled(Handle<SharedFunctionInfo> shared,
|
|
||||||
ClearExceptionFlag flag);
|
|
||||||
|
|
||||||
bool CompileLazyShared(Handle<SharedFunctionInfo> shared,
|
|
||||||
ClearExceptionFlag flag);
|
|
||||||
|
|
||||||
bool CompileLazy(Handle<JSFunction> function, ClearExceptionFlag flag);
|
|
||||||
|
|
||||||
bool CompileOptimized(Handle<JSFunction> function,
|
|
||||||
int osr_ast_id,
|
|
||||||
ClearExceptionFlag flag);
|
|
||||||
|
|
||||||
class NoHandleAllocation BASE_EMBEDDED {
|
class NoHandleAllocation BASE_EMBEDDED {
|
||||||
public:
|
public:
|
||||||
#ifndef DEBUG
|
#ifndef DEBUG
|
||||||
|
151
src/ic.cc
151
src/ic.cc
@ -445,23 +445,20 @@ static void LookupForRead(Handle<Object> object,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Object* CallICBase::TryCallAsFunction(Object* object) {
|
Handle<Object> CallICBase::TryCallAsFunction(Handle<Object> object) {
|
||||||
HandleScope scope(isolate());
|
Handle<Object> delegate = Execution::GetFunctionDelegate(object);
|
||||||
Handle<Object> target(object, isolate());
|
|
||||||
Handle<Object> delegate = Execution::GetFunctionDelegate(target);
|
|
||||||
|
|
||||||
if (delegate->IsJSFunction() && !object->IsJSFunctionProxy()) {
|
if (delegate->IsJSFunction() && !object->IsJSFunctionProxy()) {
|
||||||
// Patch the receiver and use the delegate as the function to
|
// Patch the receiver and use the delegate as the function to
|
||||||
// invoke. This is used for invoking objects as if they were
|
// invoke. This is used for invoking objects as if they were functions.
|
||||||
// functions.
|
const int argc = target()->arguments_count();
|
||||||
const int argc = this->target()->arguments_count();
|
|
||||||
StackFrameLocator locator;
|
StackFrameLocator locator;
|
||||||
JavaScriptFrame* frame = locator.FindJavaScriptFrame(0);
|
JavaScriptFrame* frame = locator.FindJavaScriptFrame(0);
|
||||||
int index = frame->ComputeExpressionsCount() - (argc + 1);
|
int index = frame->ComputeExpressionsCount() - (argc + 1);
|
||||||
frame->SetExpression(index, *target);
|
frame->SetExpression(index, *object);
|
||||||
}
|
}
|
||||||
|
|
||||||
return *delegate;
|
return delegate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -505,31 +502,27 @@ MaybeObject* CallICBase::LoadFunction(State state,
|
|||||||
// the element if so.
|
// the element if so.
|
||||||
uint32_t index;
|
uint32_t index;
|
||||||
if (name->AsArrayIndex(&index)) {
|
if (name->AsArrayIndex(&index)) {
|
||||||
Object* result;
|
Handle<Object> result = Object::GetElement(object, index);
|
||||||
{ MaybeObject* maybe_result = object->GetElement(index);
|
RETURN_IF_EMPTY_HANDLE(isolate(), result);
|
||||||
if (!maybe_result->ToObject(&result)) return maybe_result;
|
if (result->IsJSFunction()) return *result;
|
||||||
}
|
|
||||||
|
|
||||||
if (result->IsJSFunction()) return result;
|
|
||||||
|
|
||||||
// Try to find a suitable function delegate for the object at hand.
|
// Try to find a suitable function delegate for the object at hand.
|
||||||
result = TryCallAsFunction(result);
|
result = TryCallAsFunction(result);
|
||||||
if (result->IsJSFunction()) return result;
|
if (result->IsJSFunction()) return *result;
|
||||||
|
|
||||||
// Otherwise, it will fail in the lookup step.
|
// Otherwise, it will fail in the lookup step.
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lookup the property in the object.
|
// Lookup the property in the object.
|
||||||
LookupResult lookup(isolate());
|
LookupResult lookup(isolate());
|
||||||
LookupForRead(*object, *name, &lookup);
|
LookupForRead(object, name, &lookup);
|
||||||
|
|
||||||
if (!lookup.IsProperty()) {
|
if (!lookup.IsProperty()) {
|
||||||
// If the object does not have the requested property, check which
|
// If the object does not have the requested property, check which
|
||||||
// exception we need to throw.
|
// exception we need to throw.
|
||||||
if (IsContextual(object)) {
|
return IsContextual(object)
|
||||||
return ReferenceError("not_defined", name);
|
? ReferenceError("not_defined", name)
|
||||||
}
|
: TypeError("undefined_method", object, name);
|
||||||
return TypeError("undefined_method", object, name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lookup is valid: Update inline cache and stub cache.
|
// Lookup is valid: Update inline cache and stub cache.
|
||||||
@ -539,53 +532,42 @@ MaybeObject* CallICBase::LoadFunction(State state,
|
|||||||
|
|
||||||
// Get the property.
|
// Get the property.
|
||||||
PropertyAttributes attr;
|
PropertyAttributes attr;
|
||||||
Object* result;
|
Handle<Object> result =
|
||||||
{ MaybeObject* maybe_result =
|
Object::GetProperty(object, object, &lookup, name, &attr);
|
||||||
object->GetProperty(*object, &lookup, *name, &attr);
|
RETURN_IF_EMPTY_HANDLE(isolate(), result);
|
||||||
if (!maybe_result->ToObject(&result)) return maybe_result;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lookup.type() == INTERCEPTOR) {
|
if (lookup.type() == INTERCEPTOR && attr == ABSENT) {
|
||||||
// If the object does not have the requested property, check which
|
// If the object does not have the requested property, check which
|
||||||
// exception we need to throw.
|
// exception we need to throw.
|
||||||
if (attr == ABSENT) {
|
return IsContextual(object)
|
||||||
if (IsContextual(object)) {
|
? ReferenceError("not_defined", name)
|
||||||
return ReferenceError("not_defined", name);
|
: TypeError("undefined_method", object, name);
|
||||||
}
|
|
||||||
return TypeError("undefined_method", object, name);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT(!result->IsTheHole());
|
ASSERT(!result->IsTheHole());
|
||||||
|
|
||||||
HandleScope scope(isolate());
|
|
||||||
// Wrap result in a handle because ReceiverToObjectIfRequired may allocate
|
|
||||||
// new object and cause GC.
|
|
||||||
Handle<Object> result_handle(result);
|
|
||||||
// Make receiver an object if the callee requires it. Strict mode or builtin
|
// Make receiver an object if the callee requires it. Strict mode or builtin
|
||||||
// functions do not wrap the receiver, non-strict functions and objects
|
// functions do not wrap the receiver, non-strict functions and objects
|
||||||
// called as functions do.
|
// called as functions do.
|
||||||
ReceiverToObjectIfRequired(result_handle, object);
|
ReceiverToObjectIfRequired(result, object);
|
||||||
|
|
||||||
if (result_handle->IsJSFunction()) {
|
if (result->IsJSFunction()) {
|
||||||
|
Handle<JSFunction> function = Handle<JSFunction>::cast(result);
|
||||||
#ifdef ENABLE_DEBUGGER_SUPPORT
|
#ifdef ENABLE_DEBUGGER_SUPPORT
|
||||||
// Handle stepping into a function if step into is active.
|
// Handle stepping into a function if step into is active.
|
||||||
Debug* debug = isolate()->debug();
|
Debug* debug = isolate()->debug();
|
||||||
if (debug->StepInActive()) {
|
if (debug->StepInActive()) {
|
||||||
// Protect the result in a handle as the debugger can allocate and might
|
// Protect the result in a handle as the debugger can allocate and might
|
||||||
// cause GC.
|
// cause GC.
|
||||||
Handle<JSFunction> function(JSFunction::cast(*result_handle), isolate());
|
|
||||||
debug->HandleStepIn(function, object, fp(), false);
|
debug->HandleStepIn(function, object, fp(), false);
|
||||||
return *function;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
return *function;
|
||||||
return *result_handle;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to find a suitable function delegate for the object at hand.
|
// Try to find a suitable function delegate for the object at hand.
|
||||||
result_handle = Handle<Object>(TryCallAsFunction(*result_handle));
|
result = TryCallAsFunction(result);
|
||||||
if (result_handle->IsJSFunction()) return *result_handle;
|
if (result->IsJSFunction()) return *result;
|
||||||
|
|
||||||
return TypeError("property_not_function", object, name);
|
return TypeError("property_not_function", object, name);
|
||||||
}
|
}
|
||||||
@ -827,26 +809,25 @@ MaybeObject* KeyedCallIC::LoadFunction(State state,
|
|||||||
|
|
||||||
if (FLAG_use_ic && state != MEGAMORPHIC && object->IsHeapObject()) {
|
if (FLAG_use_ic && state != MEGAMORPHIC && object->IsHeapObject()) {
|
||||||
int argc = target()->arguments_count();
|
int argc = target()->arguments_count();
|
||||||
Heap* heap = Handle<HeapObject>::cast(object)->GetHeap();
|
Handle<Map> map =
|
||||||
Map* map = heap->non_strict_arguments_elements_map();
|
isolate()->factory()->non_strict_arguments_elements_map();
|
||||||
if (object->IsJSObject() &&
|
if (object->IsJSObject() &&
|
||||||
Handle<JSObject>::cast(object)->elements()->map() == map) {
|
Handle<JSObject>::cast(object)->elements()->map() == *map) {
|
||||||
MaybeObject* maybe_code = isolate()->stub_cache()->ComputeCallArguments(
|
MaybeObject* maybe_code = isolate()->stub_cache()->ComputeCallArguments(
|
||||||
argc, Code::KEYED_CALL_IC);
|
argc, Code::KEYED_CALL_IC);
|
||||||
Object* code;
|
Code* code = NULL;
|
||||||
if (maybe_code->ToObject(&code)) {
|
if (maybe_code->To(&code)) {
|
||||||
set_target(Code::cast(code));
|
set_target(code);
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
TraceIC("KeyedCallIC", key, state, target());
|
TraceIC("KeyedCallIC", key, state, target());
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
} else if (FLAG_use_ic && state != MEGAMORPHIC &&
|
} else if (!object->IsAccessCheckNeeded()) {
|
||||||
!object->IsAccessCheckNeeded()) {
|
|
||||||
MaybeObject* maybe_code = isolate()->stub_cache()->ComputeCallMegamorphic(
|
MaybeObject* maybe_code = isolate()->stub_cache()->ComputeCallMegamorphic(
|
||||||
argc, Code::KEYED_CALL_IC, Code::kNoExtraICState);
|
argc, Code::KEYED_CALL_IC, Code::kNoExtraICState);
|
||||||
Object* code;
|
Code* code;
|
||||||
if (maybe_code->ToObject(&code)) {
|
if (maybe_code->To(&code)) {
|
||||||
set_target(Code::cast(code));
|
set_target(code);
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
TraceIC("KeyedCallIC", key, state, target());
|
TraceIC("KeyedCallIC", key, state, target());
|
||||||
#endif
|
#endif
|
||||||
@ -854,7 +835,6 @@ MaybeObject* KeyedCallIC::LoadFunction(State state,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HandleScope scope(isolate());
|
|
||||||
Handle<Object> result = GetProperty(object, key);
|
Handle<Object> result = GetProperty(object, key);
|
||||||
RETURN_IF_EMPTY_HANDLE(isolate(), result);
|
RETURN_IF_EMPTY_HANDLE(isolate(), result);
|
||||||
|
|
||||||
@ -862,9 +842,9 @@ MaybeObject* KeyedCallIC::LoadFunction(State state,
|
|||||||
// functions do not wrap the receiver, non-strict functions and objects
|
// functions do not wrap the receiver, non-strict functions and objects
|
||||||
// called as functions do.
|
// called as functions do.
|
||||||
ReceiverToObjectIfRequired(result, object);
|
ReceiverToObjectIfRequired(result, object);
|
||||||
|
|
||||||
if (result->IsJSFunction()) return *result;
|
if (result->IsJSFunction()) return *result;
|
||||||
result = Handle<Object>(TryCallAsFunction(*result));
|
|
||||||
|
result = TryCallAsFunction(result);
|
||||||
if (result->IsJSFunction()) return *result;
|
if (result->IsJSFunction()) return *result;
|
||||||
|
|
||||||
return TypeError("property_not_function", object, key);
|
return TypeError("property_not_function", object, key);
|
||||||
@ -981,7 +961,7 @@ MaybeObject* LoadIC::Load(State state,
|
|||||||
(lookup.type() == INTERCEPTOR || lookup.type() == HANDLER)) {
|
(lookup.type() == INTERCEPTOR || lookup.type() == HANDLER)) {
|
||||||
// Get the property.
|
// Get the property.
|
||||||
Handle<Object> result =
|
Handle<Object> result =
|
||||||
Object::GetProperty(isolate(), object, object, &lookup, name, &attr);
|
Object::GetProperty(object, object, &lookup, name, &attr);
|
||||||
RETURN_IF_EMPTY_HANDLE(isolate(), result);
|
RETURN_IF_EMPTY_HANDLE(isolate(), result);
|
||||||
// If the property is not present, check if we need to throw an
|
// If the property is not present, check if we need to throw an
|
||||||
// exception.
|
// exception.
|
||||||
@ -1996,19 +1976,9 @@ void KeyedStoreIC::UpdateCaches(LookupResult* lookup,
|
|||||||
// Static IC stub generators.
|
// Static IC stub generators.
|
||||||
//
|
//
|
||||||
|
|
||||||
static JSFunction* CompileFunction(Isolate* isolate,
|
|
||||||
JSFunction* function) {
|
|
||||||
// Compile now with optimization.
|
|
||||||
HandleScope scope(isolate);
|
|
||||||
Handle<JSFunction> function_handle(function, isolate);
|
|
||||||
CompileLazy(function_handle, CLEAR_EXCEPTION);
|
|
||||||
return *function_handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Used from ic-<arch>.cc.
|
// Used from ic-<arch>.cc.
|
||||||
RUNTIME_FUNCTION(MaybeObject*, CallIC_Miss) {
|
RUNTIME_FUNCTION(MaybeObject*, CallIC_Miss) {
|
||||||
NoHandleAllocation na;
|
HandleScope scope(isolate);
|
||||||
ASSERT(args.length() == 2);
|
ASSERT(args.length() == 2);
|
||||||
CallIC ic(isolate);
|
CallIC ic(isolate);
|
||||||
IC::State state = IC::StateFrom(ic.target(), args[0], args[1]);
|
IC::State state = IC::StateFrom(ic.target(), args[0], args[1]);
|
||||||
@ -2017,39 +1987,40 @@ RUNTIME_FUNCTION(MaybeObject*, CallIC_Miss) {
|
|||||||
extra_ic_state,
|
extra_ic_state,
|
||||||
args.at<Object>(0),
|
args.at<Object>(0),
|
||||||
args.at<String>(1));
|
args.at<String>(1));
|
||||||
Object* result;
|
// Result could be a function or a failure.
|
||||||
if (!maybe_result->ToObject(&result)) return maybe_result;
|
JSFunction* raw_function = NULL;
|
||||||
|
if (!maybe_result->To(&raw_function)) return maybe_result;
|
||||||
|
|
||||||
// The first time the inline cache is updated may be the first time the
|
// The first time the inline cache is updated may be the first time the
|
||||||
// function it references gets called. If the function was lazily compiled
|
// function it references gets called. If the function is lazily compiled
|
||||||
// then the first call will trigger a compilation. We check for this case
|
// then the first call will trigger a compilation. We check for this case
|
||||||
// and we do the compilation immediately, instead of waiting for the stub
|
// and we do the compilation immediately, instead of waiting for the stub
|
||||||
// currently attached to the JSFunction object to trigger compilation. We
|
// currently attached to the JSFunction object to trigger compilation.
|
||||||
// do this in the case where we know that the inline cache is inside a loop,
|
if (raw_function->is_compiled()) return raw_function;
|
||||||
// because then we know that we want to optimize the function.
|
|
||||||
if (!result->IsJSFunction() || JSFunction::cast(result)->is_compiled()) {
|
Handle<JSFunction> function(raw_function);
|
||||||
return result;
|
JSFunction::CompileLazy(function, CLEAR_EXCEPTION);
|
||||||
}
|
return *function;
|
||||||
return CompileFunction(isolate, JSFunction::cast(result));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Used from ic-<arch>.cc.
|
// Used from ic-<arch>.cc.
|
||||||
RUNTIME_FUNCTION(MaybeObject*, KeyedCallIC_Miss) {
|
RUNTIME_FUNCTION(MaybeObject*, KeyedCallIC_Miss) {
|
||||||
NoHandleAllocation na;
|
HandleScope scope(isolate);
|
||||||
ASSERT(args.length() == 2);
|
ASSERT(args.length() == 2);
|
||||||
KeyedCallIC ic(isolate);
|
KeyedCallIC ic(isolate);
|
||||||
IC::State state = IC::StateFrom(ic.target(), args[0], args[1]);
|
IC::State state = IC::StateFrom(ic.target(), args[0], args[1]);
|
||||||
Object* result;
|
MaybeObject* maybe_result =
|
||||||
{ MaybeObject* maybe_result =
|
|
||||||
ic.LoadFunction(state, args.at<Object>(0), args.at<Object>(1));
|
ic.LoadFunction(state, args.at<Object>(0), args.at<Object>(1));
|
||||||
if (!maybe_result->ToObject(&result)) return maybe_result;
|
// Result could be a function or a failure.
|
||||||
}
|
JSFunction* raw_function = NULL;
|
||||||
|
if (!maybe_result->To(&raw_function)) return maybe_result;
|
||||||
|
|
||||||
if (!result->IsJSFunction() || JSFunction::cast(result)->is_compiled()) {
|
if (raw_function->is_compiled()) return raw_function;
|
||||||
return result;
|
|
||||||
}
|
Handle<JSFunction> function(raw_function);
|
||||||
return CompileFunction(isolate, JSFunction::cast(result));
|
JSFunction::CompileLazy(function, CLEAR_EXCEPTION);
|
||||||
|
return *function;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
13
src/ic.h
13
src/ic.h
@ -203,6 +203,7 @@ class CallICBase: public IC {
|
|||||||
: IC(EXTRA_CALL_FRAME, isolate), kind_(kind) {}
|
: IC(EXTRA_CALL_FRAME, isolate), kind_(kind) {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
// Returns a JSFunction or a Failure.
|
||||||
MUST_USE_RESULT MaybeObject* LoadFunction(State state,
|
MUST_USE_RESULT MaybeObject* LoadFunction(State state,
|
||||||
Code::ExtraICState extra_ic_state,
|
Code::ExtraICState extra_ic_state,
|
||||||
Handle<Object> object,
|
Handle<Object> object,
|
||||||
@ -222,18 +223,18 @@ class CallICBase: public IC {
|
|||||||
Handle<Object> object,
|
Handle<Object> object,
|
||||||
Handle<String> name);
|
Handle<String> name);
|
||||||
|
|
||||||
// Update the inline cache and the global stub cache based on the
|
// Update the inline cache and the global stub cache based on the lookup
|
||||||
// lookup result.
|
// result.
|
||||||
void UpdateCaches(LookupResult* lookup,
|
void UpdateCaches(LookupResult* lookup,
|
||||||
State state,
|
State state,
|
||||||
Code::ExtraICState extra_ic_state,
|
Code::ExtraICState extra_ic_state,
|
||||||
Handle<Object> object,
|
Handle<Object> object,
|
||||||
Handle<String> name);
|
Handle<String> name);
|
||||||
|
|
||||||
// Returns a JSFunction if the object can be called as a function,
|
// Returns a JSFunction if the object can be called as a function, and
|
||||||
// and patches the stack to be ready for the call.
|
// patches the stack to be ready for the call. Otherwise, it returns the
|
||||||
// Otherwise, it returns the undefined value.
|
// undefined value.
|
||||||
Object* TryCallAsFunction(Object* object);
|
Handle<Object> TryCallAsFunction(Handle<Object> object);
|
||||||
|
|
||||||
void ReceiverToObjectIfRequired(Handle<Object> callee, Handle<Object> object);
|
void ReceiverToObjectIfRequired(Handle<Object> callee, Handle<Object> object);
|
||||||
|
|
||||||
|
@ -234,6 +234,14 @@ MaybeObject* JSProxy::GetPropertyWithHandler(Object* receiver_raw,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Handle<Object> Object::GetElement(Handle<Object> object, uint32_t index) {
|
||||||
|
Isolate* isolate = object->IsHeapObject()
|
||||||
|
? Handle<HeapObject>::cast(object)->GetIsolate()
|
||||||
|
: Isolate::Current();
|
||||||
|
CALL_HEAP_FUNCTION(isolate, object->GetElement(index), Object);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
MaybeObject* JSProxy::GetElementWithHandler(Object* receiver,
|
MaybeObject* JSProxy::GetElementWithHandler(Object* receiver,
|
||||||
uint32_t index) {
|
uint32_t index) {
|
||||||
String* name;
|
String* name;
|
||||||
@ -528,12 +536,14 @@ bool JSObject::IsDirty() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Handle<Object> Object::GetProperty(Isolate* isolate,
|
Handle<Object> Object::GetProperty(Handle<Object> object,
|
||||||
Handle<Object> object,
|
|
||||||
Handle<Object> receiver,
|
Handle<Object> receiver,
|
||||||
LookupResult* result,
|
LookupResult* result,
|
||||||
Handle<String> key,
|
Handle<String> key,
|
||||||
PropertyAttributes* attributes) {
|
PropertyAttributes* attributes) {
|
||||||
|
Isolate* isolate = object->IsHeapObject()
|
||||||
|
? Handle<HeapObject>::cast(object)->GetIsolate()
|
||||||
|
: Isolate::Current();
|
||||||
CALL_HEAP_FUNCTION(
|
CALL_HEAP_FUNCTION(
|
||||||
isolate,
|
isolate,
|
||||||
object->GetProperty(*receiver, result, *key, attributes),
|
object->GetProperty(*receiver, result, *key, attributes),
|
||||||
@ -6941,6 +6951,57 @@ void JSFunction::MarkForLazyRecompilation() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool SharedFunctionInfo::EnsureCompiled(Handle<SharedFunctionInfo> shared,
|
||||||
|
ClearExceptionFlag flag) {
|
||||||
|
return shared->is_compiled() || CompileLazy(shared, flag);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool CompileLazyHelper(CompilationInfo* info,
|
||||||
|
ClearExceptionFlag flag) {
|
||||||
|
// Compile the source information to a code object.
|
||||||
|
ASSERT(info->IsOptimizing() || !info->shared_info()->is_compiled());
|
||||||
|
ASSERT(!info->isolate()->has_pending_exception());
|
||||||
|
bool result = Compiler::CompileLazy(info);
|
||||||
|
ASSERT(result != Isolate::Current()->has_pending_exception());
|
||||||
|
if (!result && flag == CLEAR_EXCEPTION) {
|
||||||
|
info->isolate()->clear_pending_exception();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool SharedFunctionInfo::CompileLazy(Handle<SharedFunctionInfo> shared,
|
||||||
|
ClearExceptionFlag flag) {
|
||||||
|
CompilationInfo info(shared);
|
||||||
|
return CompileLazyHelper(&info, flag);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool JSFunction::CompileLazy(Handle<JSFunction> function,
|
||||||
|
ClearExceptionFlag flag) {
|
||||||
|
bool result = true;
|
||||||
|
if (function->shared()->is_compiled()) {
|
||||||
|
function->ReplaceCode(function->shared()->code());
|
||||||
|
function->shared()->set_code_age(0);
|
||||||
|
} else {
|
||||||
|
CompilationInfo info(function);
|
||||||
|
result = CompileLazyHelper(&info, flag);
|
||||||
|
ASSERT(!result || function->is_compiled());
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool JSFunction::CompileOptimized(Handle<JSFunction> function,
|
||||||
|
int osr_ast_id,
|
||||||
|
ClearExceptionFlag flag) {
|
||||||
|
CompilationInfo info(function);
|
||||||
|
info.SetOptimizing(osr_ast_id);
|
||||||
|
return CompileLazyHelper(&info, flag);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool JSFunction::IsInlineable() {
|
bool JSFunction::IsInlineable() {
|
||||||
if (IsBuiltin()) return false;
|
if (IsBuiltin()) return false;
|
||||||
SharedFunctionInfo* shared_info = shared();
|
SharedFunctionInfo* shared_info = shared();
|
||||||
|
@ -913,8 +913,7 @@ class Object : public MaybeObject {
|
|||||||
String* key,
|
String* key,
|
||||||
PropertyAttributes* attributes);
|
PropertyAttributes* attributes);
|
||||||
|
|
||||||
static Handle<Object> GetProperty(Isolate* isolate,
|
static Handle<Object> GetProperty(Handle<Object> object,
|
||||||
Handle<Object> object,
|
|
||||||
Handle<Object> receiver,
|
Handle<Object> receiver,
|
||||||
LookupResult* result,
|
LookupResult* result,
|
||||||
Handle<String> key,
|
Handle<String> key,
|
||||||
@ -928,6 +927,7 @@ class Object : public MaybeObject {
|
|||||||
MUST_USE_RESULT MaybeObject* GetPropertyWithDefinedGetter(Object* receiver,
|
MUST_USE_RESULT MaybeObject* GetPropertyWithDefinedGetter(Object* receiver,
|
||||||
JSReceiver* getter);
|
JSReceiver* getter);
|
||||||
|
|
||||||
|
static Handle<Object> GetElement(Handle<Object> object, uint32_t index);
|
||||||
inline MaybeObject* GetElement(uint32_t index);
|
inline MaybeObject* GetElement(uint32_t index);
|
||||||
// For use when we know that no exception can be thrown.
|
// For use when we know that no exception can be thrown.
|
||||||
inline Object* GetElementNoExceptionThrown(uint32_t index);
|
inline Object* GetElementNoExceptionThrown(uint32_t index);
|
||||||
@ -4917,6 +4917,13 @@ class SharedFunctionInfo: public HeapObject {
|
|||||||
void SharedFunctionInfoVerify();
|
void SharedFunctionInfoVerify();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Helpers to compile the shared code. Returns true on success, false on
|
||||||
|
// failure (e.g., stack overflow during compilation).
|
||||||
|
static bool EnsureCompiled(Handle<SharedFunctionInfo> shared,
|
||||||
|
ClearExceptionFlag flag);
|
||||||
|
static bool CompileLazy(Handle<SharedFunctionInfo> shared,
|
||||||
|
ClearExceptionFlag flag);
|
||||||
|
|
||||||
// Casting.
|
// Casting.
|
||||||
static inline SharedFunctionInfo* cast(Object* obj);
|
static inline SharedFunctionInfo* cast(Object* obj);
|
||||||
|
|
||||||
@ -5138,6 +5145,14 @@ class JSFunction: public JSObject {
|
|||||||
// recompiled the next time it is executed.
|
// recompiled the next time it is executed.
|
||||||
void MarkForLazyRecompilation();
|
void MarkForLazyRecompilation();
|
||||||
|
|
||||||
|
// Helpers to compile this function. Returns true on success, false on
|
||||||
|
// failure (e.g., stack overflow during compilation).
|
||||||
|
static bool CompileLazy(Handle<JSFunction> function,
|
||||||
|
ClearExceptionFlag flag);
|
||||||
|
static bool CompileOptimized(Handle<JSFunction> function,
|
||||||
|
int osr_ast_id,
|
||||||
|
ClearExceptionFlag flag);
|
||||||
|
|
||||||
// Tells whether or not the function is already marked for lazy
|
// Tells whether or not the function is already marked for lazy
|
||||||
// recompilation.
|
// recompilation.
|
||||||
inline bool IsMarkedForLazyRecompilation();
|
inline bool IsMarkedForLazyRecompilation();
|
||||||
|
@ -1005,7 +1005,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOwnProperty) {
|
|||||||
case JSObject::INTERCEPTED_ELEMENT:
|
case JSObject::INTERCEPTED_ELEMENT:
|
||||||
case JSObject::FAST_ELEMENT: {
|
case JSObject::FAST_ELEMENT: {
|
||||||
elms->set(IS_ACCESSOR_INDEX, heap->false_value());
|
elms->set(IS_ACCESSOR_INDEX, heap->false_value());
|
||||||
Handle<Object> value = GetElement(obj, index);
|
Handle<Object> value = Object::GetElement(obj, index);
|
||||||
RETURN_IF_EMPTY_HANDLE(isolate, value);
|
RETURN_IF_EMPTY_HANDLE(isolate, value);
|
||||||
elms->set(VALUE_INDEX, *value);
|
elms->set(VALUE_INDEX, *value);
|
||||||
elms->set(WRITABLE_INDEX, heap->true_value());
|
elms->set(WRITABLE_INDEX, heap->true_value());
|
||||||
@ -1049,7 +1049,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOwnProperty) {
|
|||||||
case NORMAL: {
|
case NORMAL: {
|
||||||
// This is a data property.
|
// This is a data property.
|
||||||
elms->set(IS_ACCESSOR_INDEX, heap->false_value());
|
elms->set(IS_ACCESSOR_INDEX, heap->false_value());
|
||||||
Handle<Object> value = GetElement(obj, index);
|
Handle<Object> value = Object::GetElement(obj, index);
|
||||||
ASSERT(!value.is_null());
|
ASSERT(!value.is_null());
|
||||||
elms->set(VALUE_INDEX, *value);
|
elms->set(VALUE_INDEX, *value);
|
||||||
elms->set(WRITABLE_INDEX, heap->ToBoolean(!details.IsReadOnly()));
|
elms->set(WRITABLE_INDEX, heap->ToBoolean(!details.IsReadOnly()));
|
||||||
@ -2110,7 +2110,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SetCode) {
|
|||||||
Handle<JSFunction> fun = Handle<JSFunction>::cast(code);
|
Handle<JSFunction> fun = Handle<JSFunction>::cast(code);
|
||||||
Handle<SharedFunctionInfo> shared(fun->shared());
|
Handle<SharedFunctionInfo> shared(fun->shared());
|
||||||
|
|
||||||
if (!EnsureCompiled(shared, KEEP_EXCEPTION)) {
|
if (!SharedFunctionInfo::EnsureCompiled(shared, KEEP_EXCEPTION)) {
|
||||||
return Failure::Exception();
|
return Failure::Exception();
|
||||||
}
|
}
|
||||||
// Since we don't store the source for this we should never
|
// Since we don't store the source for this we should never
|
||||||
@ -4042,11 +4042,6 @@ MaybeObject* Runtime::GetElementOrCharAt(Isolate* isolate,
|
|||||||
return prototype->GetElement(index);
|
return prototype->GetElement(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
return GetElement(object, index);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
MaybeObject* Runtime::GetElement(Handle<Object> object, uint32_t index) {
|
|
||||||
return object->GetElement(index);
|
return object->GetElement(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -8141,9 +8136,11 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NewObject) {
|
|||||||
// available. We cannot use EnsureCompiled because that forces a
|
// available. We cannot use EnsureCompiled because that forces a
|
||||||
// compilation through the shared function info which makes it
|
// compilation through the shared function info which makes it
|
||||||
// impossible for us to optimize.
|
// impossible for us to optimize.
|
||||||
Handle<SharedFunctionInfo> shared(function->shared(), isolate);
|
if (!function->is_compiled()) {
|
||||||
if (!function->is_compiled()) CompileLazy(function, CLEAR_EXCEPTION);
|
JSFunction::CompileLazy(function, CLEAR_EXCEPTION);
|
||||||
|
}
|
||||||
|
|
||||||
|
Handle<SharedFunctionInfo> shared(function->shared(), isolate);
|
||||||
if (!function->has_initial_map() &&
|
if (!function->has_initial_map() &&
|
||||||
shared->IsInobjectSlackTrackingInProgress()) {
|
shared->IsInobjectSlackTrackingInProgress()) {
|
||||||
// The tracking is already in progress for another function. We can only
|
// The tracking is already in progress for another function. We can only
|
||||||
@ -8194,7 +8191,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_LazyCompile) {
|
|||||||
|
|
||||||
// Compile the target function.
|
// Compile the target function.
|
||||||
ASSERT(!function->is_compiled());
|
ASSERT(!function->is_compiled());
|
||||||
if (!CompileLazy(function, KEEP_EXCEPTION)) {
|
if (!JSFunction::CompileLazy(function, KEEP_EXCEPTION)) {
|
||||||
return Failure::Exception();
|
return Failure::Exception();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -8231,7 +8228,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_LazyRecompile) {
|
|||||||
function->ReplaceCode(function->shared()->code());
|
function->ReplaceCode(function->shared()->code());
|
||||||
return function->code();
|
return function->code();
|
||||||
}
|
}
|
||||||
if (CompileOptimized(function, AstNode::kNoNumber, CLEAR_EXCEPTION)) {
|
if (JSFunction::CompileOptimized(function,
|
||||||
|
AstNode::kNoNumber,
|
||||||
|
CLEAR_EXCEPTION)) {
|
||||||
return function->code();
|
return function->code();
|
||||||
}
|
}
|
||||||
if (FLAG_trace_opt) {
|
if (FLAG_trace_opt) {
|
||||||
@ -8472,7 +8471,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CompileForOnStackReplacement) {
|
|||||||
// Try to compile the optimized code. A true return value from
|
// Try to compile the optimized code. A true return value from
|
||||||
// CompileOptimized means that compilation succeeded, not necessarily
|
// CompileOptimized means that compilation succeeded, not necessarily
|
||||||
// that optimization succeeded.
|
// that optimization succeeded.
|
||||||
if (CompileOptimized(function, ast_id, CLEAR_EXCEPTION) &&
|
if (JSFunction::CompileOptimized(function, ast_id, CLEAR_EXCEPTION) &&
|
||||||
function->IsOptimized()) {
|
function->IsOptimized()) {
|
||||||
DeoptimizationInputData* data = DeoptimizationInputData::cast(
|
DeoptimizationInputData* data = DeoptimizationInputData::cast(
|
||||||
function->code()->deoptimization_data());
|
function->code()->deoptimization_data());
|
||||||
@ -9847,8 +9846,8 @@ static bool IterateElements(Isolate* isolate,
|
|||||||
} else if (receiver->HasElement(j)) {
|
} else if (receiver->HasElement(j)) {
|
||||||
// Call GetElement on receiver, not its prototype, or getters won't
|
// Call GetElement on receiver, not its prototype, or getters won't
|
||||||
// have the correct receiver.
|
// have the correct receiver.
|
||||||
element_value = GetElement(receiver, j);
|
element_value = Object::GetElement(receiver, j);
|
||||||
if (element_value.is_null()) return false;
|
RETURN_IF_EMPTY_HANDLE_VALUE(isolate, element_value, false);
|
||||||
visitor->visit(j, element_value);
|
visitor->visit(j, element_value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -9866,8 +9865,8 @@ static bool IterateElements(Isolate* isolate,
|
|||||||
while (j < n) {
|
while (j < n) {
|
||||||
HandleScope loop_scope;
|
HandleScope loop_scope;
|
||||||
uint32_t index = indices[j];
|
uint32_t index = indices[j];
|
||||||
Handle<Object> element = GetElement(receiver, index);
|
Handle<Object> element = Object::GetElement(receiver, index);
|
||||||
if (element.is_null()) return false;
|
RETURN_IF_EMPTY_HANDLE_VALUE(isolate, element, false);
|
||||||
visitor->visit(index, element);
|
visitor->visit(index, element);
|
||||||
// Skip to next different index (i.e., omit duplicates).
|
// Skip to next different index (i.e., omit duplicates).
|
||||||
do {
|
do {
|
||||||
@ -10117,9 +10116,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SwapElements) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Handle<JSObject> jsobject = Handle<JSObject>::cast(object);
|
Handle<JSObject> jsobject = Handle<JSObject>::cast(object);
|
||||||
Handle<Object> tmp1 = GetElement(jsobject, index1);
|
Handle<Object> tmp1 = Object::GetElement(jsobject, index1);
|
||||||
RETURN_IF_EMPTY_HANDLE(isolate, tmp1);
|
RETURN_IF_EMPTY_HANDLE(isolate, tmp1);
|
||||||
Handle<Object> tmp2 = GetElement(jsobject, index2);
|
Handle<Object> tmp2 = Object::GetElement(jsobject, index2);
|
||||||
RETURN_IF_EMPTY_HANDLE(isolate, tmp2);
|
RETURN_IF_EMPTY_HANDLE(isolate, tmp2);
|
||||||
|
|
||||||
RETURN_IF_EMPTY_HANDLE(isolate,
|
RETURN_IF_EMPTY_HANDLE(isolate,
|
||||||
@ -11629,7 +11628,7 @@ Object* Runtime::FindSharedFunctionInfoInScript(Isolate* isolate,
|
|||||||
if (!done) {
|
if (!done) {
|
||||||
// If the candidate is not compiled compile it to reveal any inner
|
// If the candidate is not compiled compile it to reveal any inner
|
||||||
// functions which might contain the requested source position.
|
// functions which might contain the requested source position.
|
||||||
CompileLazyShared(target, KEEP_EXCEPTION);
|
SharedFunctionInfo::CompileLazy(target, KEEP_EXCEPTION);
|
||||||
}
|
}
|
||||||
} // End while loop.
|
} // End while loop.
|
||||||
|
|
||||||
@ -12376,7 +12375,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugDisassembleFunction) {
|
|||||||
// Get the function and make sure it is compiled.
|
// Get the function and make sure it is compiled.
|
||||||
CONVERT_ARG_CHECKED(JSFunction, func, 0);
|
CONVERT_ARG_CHECKED(JSFunction, func, 0);
|
||||||
Handle<SharedFunctionInfo> shared(func->shared());
|
Handle<SharedFunctionInfo> shared(func->shared());
|
||||||
if (!EnsureCompiled(shared, KEEP_EXCEPTION)) {
|
if (!SharedFunctionInfo::EnsureCompiled(shared, KEEP_EXCEPTION)) {
|
||||||
return Failure::Exception();
|
return Failure::Exception();
|
||||||
}
|
}
|
||||||
func->code()->PrintLn();
|
func->code()->PrintLn();
|
||||||
@ -12392,7 +12391,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugDisassembleConstructor) {
|
|||||||
// Get the function and make sure it is compiled.
|
// Get the function and make sure it is compiled.
|
||||||
CONVERT_ARG_CHECKED(JSFunction, func, 0);
|
CONVERT_ARG_CHECKED(JSFunction, func, 0);
|
||||||
Handle<SharedFunctionInfo> shared(func->shared());
|
Handle<SharedFunctionInfo> shared(func->shared());
|
||||||
if (!EnsureCompiled(shared, KEEP_EXCEPTION)) {
|
if (!SharedFunctionInfo::EnsureCompiled(shared, KEEP_EXCEPTION)) {
|
||||||
return Failure::Exception();
|
return Failure::Exception();
|
||||||
}
|
}
|
||||||
shared->construct_stub()->PrintLn();
|
shared->construct_stub()->PrintLn();
|
||||||
|
@ -626,16 +626,14 @@ class Runtime : public AllStatic {
|
|||||||
|
|
||||||
static bool IsUpperCaseChar(RuntimeState* runtime_state, uint16_t ch);
|
static bool IsUpperCaseChar(RuntimeState* runtime_state, uint16_t ch);
|
||||||
|
|
||||||
// TODO(1240886): The following three methods are *not* handle safe,
|
// TODO(1240886): Some of the following methods are *not* handle safe, but
|
||||||
// but accept handle arguments. This seems fragile.
|
// accept handle arguments. This seems fragile.
|
||||||
|
|
||||||
// Support getting the characters in a string using [] notation as
|
// Support getting the characters in a string using [] notation as
|
||||||
// in Firefox/SpiderMonkey, Safari and Opera.
|
// in Firefox/SpiderMonkey, Safari and Opera.
|
||||||
MUST_USE_RESULT static MaybeObject* GetElementOrCharAt(Isolate* isolate,
|
MUST_USE_RESULT static MaybeObject* GetElementOrCharAt(Isolate* isolate,
|
||||||
Handle<Object> object,
|
Handle<Object> object,
|
||||||
uint32_t index);
|
uint32_t index);
|
||||||
MUST_USE_RESULT static MaybeObject* GetElement(Handle<Object> object,
|
|
||||||
uint32_t index);
|
|
||||||
|
|
||||||
MUST_USE_RESULT static MaybeObject* SetObjectProperty(
|
MUST_USE_RESULT static MaybeObject* SetObjectProperty(
|
||||||
Isolate* isolate,
|
Isolate* isolate,
|
||||||
|
@ -557,6 +557,13 @@ enum VariableMode {
|
|||||||
// in a context
|
// in a context
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
enum ClearExceptionFlag {
|
||||||
|
KEEP_EXCEPTION,
|
||||||
|
CLEAR_EXCEPTION
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
} } // namespace v8::internal
|
} } // namespace v8::internal
|
||||||
|
|
||||||
#endif // V8_V8GLOBALS_H_
|
#endif // V8_V8GLOBALS_H_
|
||||||
|
Loading…
Reference in New Issue
Block a user