Index: src/ic.cc |
diff --git a/src/ic.cc b/src/ic.cc |
index 107338caeeb14dd598e2711aa0e9b2c121c6f91f..45dba360b91a2ce8f228764befc93888fce5ae58 100644 |
--- a/src/ic.cc |
+++ b/src/ic.cc |
@@ -445,23 +445,20 @@ static void LookupForRead(Handle<Object> object, |
} |
-Object* CallICBase::TryCallAsFunction(Object* object) { |
- HandleScope scope(isolate()); |
- Handle<Object> target(object, isolate()); |
- Handle<Object> delegate = Execution::GetFunctionDelegate(target); |
+Handle<Object> CallICBase::TryCallAsFunction(Handle<Object> object) { |
+ Handle<Object> delegate = Execution::GetFunctionDelegate(object); |
if (delegate->IsJSFunction() && !object->IsJSFunctionProxy()) { |
// Patch the receiver and use the delegate as the function to |
- // invoke. This is used for invoking objects as if they were |
- // functions. |
- const int argc = this->target()->arguments_count(); |
+ // invoke. This is used for invoking objects as if they were functions. |
+ const int argc = target()->arguments_count(); |
StackFrameLocator locator; |
JavaScriptFrame* frame = locator.FindJavaScriptFrame(0); |
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. |
uint32_t index; |
if (name->AsArrayIndex(&index)) { |
- Object* result; |
- { MaybeObject* maybe_result = object->GetElement(index); |
- if (!maybe_result->ToObject(&result)) return maybe_result; |
- } |
- |
- if (result->IsJSFunction()) return result; |
+ Handle<Object> result = Object::GetElement(object, index); |
+ RETURN_IF_EMPTY_HANDLE(isolate(), result); |
+ if (result->IsJSFunction()) return *result; |
// Try to find a suitable function delegate for the object at hand. |
result = TryCallAsFunction(result); |
- if (result->IsJSFunction()) return result; |
+ if (result->IsJSFunction()) return *result; |
// Otherwise, it will fail in the lookup step. |
} |
// Lookup the property in the object. |
LookupResult lookup(isolate()); |
- LookupForRead(*object, *name, &lookup); |
+ LookupForRead(object, name, &lookup); |
if (!lookup.IsProperty()) { |
// If the object does not have the requested property, check which |
// exception we need to throw. |
- if (IsContextual(object)) { |
- return ReferenceError("not_defined", name); |
- } |
- return TypeError("undefined_method", object, name); |
+ return IsContextual(object) |
+ ? ReferenceError("not_defined", name) |
+ : TypeError("undefined_method", object, name); |
} |
// Lookup is valid: Update inline cache and stub cache. |
@@ -539,53 +532,42 @@ MaybeObject* CallICBase::LoadFunction(State state, |
// Get the property. |
PropertyAttributes attr; |
- Object* result; |
- { MaybeObject* maybe_result = |
- object->GetProperty(*object, &lookup, *name, &attr); |
- if (!maybe_result->ToObject(&result)) return maybe_result; |
- } |
+ Handle<Object> result = |
+ Object::GetProperty(object, object, &lookup, name, &attr); |
+ RETURN_IF_EMPTY_HANDLE(isolate(), result); |
- if (lookup.type() == INTERCEPTOR) { |
+ if (lookup.type() == INTERCEPTOR && attr == ABSENT) { |
// If the object does not have the requested property, check which |
// exception we need to throw. |
- if (attr == ABSENT) { |
- if (IsContextual(object)) { |
- return ReferenceError("not_defined", name); |
- } |
- return TypeError("undefined_method", object, name); |
- } |
+ return IsContextual(object) |
+ ? ReferenceError("not_defined", name) |
+ : TypeError("undefined_method", object, name); |
} |
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 |
// functions do not wrap the receiver, non-strict functions and objects |
// 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 |
// Handle stepping into a function if step into is active. |
Debug* debug = isolate()->debug(); |
if (debug->StepInActive()) { |
// Protect the result in a handle as the debugger can allocate and might |
// cause GC. |
- Handle<JSFunction> function(JSFunction::cast(*result_handle), isolate()); |
debug->HandleStepIn(function, object, fp(), false); |
- return *function; |
} |
#endif |
- |
- return *result_handle; |
+ return *function; |
} |
// Try to find a suitable function delegate for the object at hand. |
- result_handle = Handle<Object>(TryCallAsFunction(*result_handle)); |
- if (result_handle->IsJSFunction()) return *result_handle; |
+ result = TryCallAsFunction(result); |
+ if (result->IsJSFunction()) return *result; |
return TypeError("property_not_function", object, name); |
} |
@@ -827,26 +809,25 @@ MaybeObject* KeyedCallIC::LoadFunction(State state, |
if (FLAG_use_ic && state != MEGAMORPHIC && object->IsHeapObject()) { |
int argc = target()->arguments_count(); |
- Heap* heap = Handle<HeapObject>::cast(object)->GetHeap(); |
- Map* map = heap->non_strict_arguments_elements_map(); |
+ Handle<Map> map = |
+ isolate()->factory()->non_strict_arguments_elements_map(); |
if (object->IsJSObject() && |
- Handle<JSObject>::cast(object)->elements()->map() == map) { |
+ Handle<JSObject>::cast(object)->elements()->map() == *map) { |
MaybeObject* maybe_code = isolate()->stub_cache()->ComputeCallArguments( |
argc, Code::KEYED_CALL_IC); |
- Object* code; |
- if (maybe_code->ToObject(&code)) { |
- set_target(Code::cast(code)); |
+ Code* code = NULL; |
+ if (maybe_code->To(&code)) { |
+ set_target(code); |
#ifdef DEBUG |
TraceIC("KeyedCallIC", key, state, target()); |
#endif |
} |
- } else if (FLAG_use_ic && state != MEGAMORPHIC && |
- !object->IsAccessCheckNeeded()) { |
+ } else if (!object->IsAccessCheckNeeded()) { |
MaybeObject* maybe_code = isolate()->stub_cache()->ComputeCallMegamorphic( |
argc, Code::KEYED_CALL_IC, Code::kNoExtraICState); |
- Object* code; |
- if (maybe_code->ToObject(&code)) { |
- set_target(Code::cast(code)); |
+ Code* code; |
+ if (maybe_code->To(&code)) { |
+ set_target(code); |
#ifdef DEBUG |
TraceIC("KeyedCallIC", key, state, target()); |
#endif |
@@ -854,7 +835,6 @@ MaybeObject* KeyedCallIC::LoadFunction(State state, |
} |
} |
- HandleScope scope(isolate()); |
Handle<Object> result = GetProperty(object, key); |
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 |
// called as functions do. |
ReceiverToObjectIfRequired(result, object); |
- |
if (result->IsJSFunction()) return *result; |
- result = Handle<Object>(TryCallAsFunction(*result)); |
+ |
+ result = TryCallAsFunction(result); |
if (result->IsJSFunction()) return *result; |
return TypeError("property_not_function", object, key); |
@@ -981,7 +961,7 @@ MaybeObject* LoadIC::Load(State state, |
(lookup.type() == INTERCEPTOR || lookup.type() == HANDLER)) { |
// Get the property. |
Handle<Object> result = |
- Object::GetProperty(isolate(), object, object, &lookup, name, &attr); |
+ Object::GetProperty(object, object, &lookup, name, &attr); |
RETURN_IF_EMPTY_HANDLE(isolate(), result); |
// If the property is not present, check if we need to throw an |
// exception. |
@@ -2002,19 +1982,9 @@ void KeyedStoreIC::UpdateCaches(LookupResult* lookup, |
// 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. |
RUNTIME_FUNCTION(MaybeObject*, CallIC_Miss) { |
- NoHandleAllocation na; |
+ HandleScope scope(isolate); |
ASSERT(args.length() == 2); |
CallIC ic(isolate); |
IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); |
@@ -2023,39 +1993,40 @@ RUNTIME_FUNCTION(MaybeObject*, CallIC_Miss) { |
extra_ic_state, |
args.at<Object>(0), |
args.at<String>(1)); |
- Object* result; |
- 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; |
// 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 |
// and we do the compilation immediately, instead of waiting for the stub |
- // currently attached to the JSFunction object to trigger compilation. We |
- // do this in the case where we know that the inline cache is inside a loop, |
- // because then we know that we want to optimize the function. |
- if (!result->IsJSFunction() || JSFunction::cast(result)->is_compiled()) { |
- return result; |
- } |
- return CompileFunction(isolate, JSFunction::cast(result)); |
+ // currently attached to the JSFunction object to trigger compilation. |
+ if (raw_function->is_compiled()) return raw_function; |
+ |
+ Handle<JSFunction> function(raw_function); |
+ JSFunction::CompileLazy(function, CLEAR_EXCEPTION); |
+ return *function; |
} |
// Used from ic-<arch>.cc. |
RUNTIME_FUNCTION(MaybeObject*, KeyedCallIC_Miss) { |
- NoHandleAllocation na; |
+ HandleScope scope(isolate); |
ASSERT(args.length() == 2); |
KeyedCallIC ic(isolate); |
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)); |
- 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()) { |
- return result; |
- } |
- return CompileFunction(isolate, JSFunction::cast(result)); |
+ if (raw_function->is_compiled()) return raw_function; |
+ |
+ Handle<JSFunction> function(raw_function); |
+ JSFunction::CompileLazy(function, CLEAR_EXCEPTION); |
+ return *function; |
} |