From 838fc2776683ccc2b30e75a6a2253bc353f7a1f0 Mon Sep 17 00:00:00 2001 From: "kmillikin@chromium.org" Date: Wed, 19 Oct 2011 12:04:16 +0000 Subject: [PATCH] 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 --- src/accessors.cc | 4 +- src/api.cc | 13 ++-- src/bootstrapper.cc | 4 +- src/debug.cc | 4 +- src/handles.cc | 56 ---------------- src/handles.h | 19 ------ src/ic.cc | 151 ++++++++++++++++++-------------------------- src/ic.h | 13 ++-- src/objects.cc | 65 ++++++++++++++++++- src/objects.h | 19 +++++- src/runtime.cc | 43 ++++++------- src/runtime.h | 6 +- src/v8globals.h | 7 ++ 13 files changed, 192 insertions(+), 212 deletions(-) diff --git a/src/accessors.cc b/src/accessors.cc index 5c6c7ef00d..02998f9b8e 100644 --- a/src/accessors.cc +++ b/src/accessors.cc @@ -527,7 +527,9 @@ MaybeObject* Accessors::FunctionGetLength(Object* object, void*) { // correctly yet. Compile it now and return the right length. HandleScope scope; Handle 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()); } else { return Smi::FromInt(function->shared()->length()); diff --git a/src/api.cc b/src/api.cc index db98a0cef0..0fa6294699 100644 --- a/src/api.cc +++ b/src/api.cc @@ -2794,7 +2794,7 @@ Local v8::Object::Get(uint32_t index) { ENTER_V8(isolate); i::Handle self = Utils::OpenHandle(this); EXCEPTION_PREAMBLE(isolate); - i::Handle result = i::GetElement(self, index); + i::Handle result = i::Object::GetElement(self, index); has_pending_exception = result.is_null(); EXCEPTION_BAILOUT_CHECK(isolate, Local()); return Utils::ToLocal(result); @@ -3093,13 +3093,10 @@ static Local GetPropertyByLookup(i::Isolate* isolate, // If the property being looked up is a callback, it can throw // an exception. EXCEPTION_PREAMBLE(isolate); - PropertyAttributes attributes; - i::Handle result = i::Object::GetProperty(isolate, - receiver, - receiver, - lookup, - name, - &attributes); + PropertyAttributes ignored; + i::Handle result = + i::Object::GetProperty(receiver, receiver, lookup, name, + &ignored); has_pending_exception = result.is_null(); EXCEPTION_BAILOUT_CHECK(isolate, Local()); diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc index 56acc86aa7..04eb009c71 100644 --- a/src/bootstrapper.cc +++ b/src/bootstrapper.cc @@ -2007,7 +2007,9 @@ bool Genesis::InstallJSBuiltins(Handle builtins) { builtins->set_javascript_builtin(id, *function); Handle shared = Handle(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. function->ReplaceCode(function->shared()->code()); builtins->set_javascript_builtin_code(id, shared->code()); diff --git a/src/debug.cc b/src/debug.cc index ee2ca08a40..492b617526 100644 --- a/src/debug.cc +++ b/src/debug.cc @@ -1940,7 +1940,9 @@ bool Debug::EnsureDebugInfo(Handle shared) { } // 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. Handle debug_info = FACTORY->NewDebugInfo(shared); diff --git a/src/handles.cc b/src/handles.cc index 04f950c02f..c6b1a67489 100644 --- a/src/handles.cc +++ b/src/handles.cc @@ -376,13 +376,6 @@ Handle GetProperty(Handle obj, } -Handle GetElement(Handle obj, - uint32_t index) { - Isolate* isolate = Isolate::Current(); - CALL_HEAP_FUNCTION(isolate, Runtime::GetElement(obj, index), Object); -} - - Handle GetPropertyWithInterceptor(Handle receiver, Handle holder, Handle name, @@ -888,53 +881,4 @@ Handle PutIntoObjectHashTable(Handle table, } -bool EnsureCompiled(Handle 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 shared, - ClearExceptionFlag flag) { - CompilationInfo info(shared); - return CompileLazyHelper(&info, flag); -} - - -bool CompileLazy(Handle 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 function, - int osr_ast_id, - ClearExceptionFlag flag) { - CompilationInfo info(function); - info.SetOptimizing(osr_ast_id); - return CompileLazyHelper(&info, flag); -} - } } // namespace v8::internal diff --git a/src/handles.h b/src/handles.h index fa27be5448..b0295ffa13 100644 --- a/src/handles.h +++ b/src/handles.h @@ -246,9 +246,6 @@ Handle GetProperty(Handle obj, Handle GetProperty(Handle obj, Handle key); -Handle GetElement(Handle obj, - uint32_t index); - Handle GetPropertyWithInterceptor(Handle receiver, Handle holder, Handle name, @@ -345,22 +342,6 @@ Handle PutIntoObjectHashTable(Handle table, Handle key, Handle 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 shared, - ClearExceptionFlag flag); - -bool CompileLazyShared(Handle shared, - ClearExceptionFlag flag); - -bool CompileLazy(Handle function, ClearExceptionFlag flag); - -bool CompileOptimized(Handle function, - int osr_ast_id, - ClearExceptionFlag flag); - class NoHandleAllocation BASE_EMBEDDED { public: #ifndef DEBUG diff --git a/src/ic.cc b/src/ic.cc index be28d23338..659e7fb0ad 100644 --- a/src/ic.cc +++ b/src/ic.cc @@ -445,23 +445,20 @@ static void LookupForRead(Handle object, } -Object* CallICBase::TryCallAsFunction(Object* object) { - HandleScope scope(isolate()); - Handle target(object, isolate()); - Handle delegate = Execution::GetFunctionDelegate(target); +Handle CallICBase::TryCallAsFunction(Handle object) { + Handle 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 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 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 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 function = Handle::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 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(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::cast(object)->GetHeap(); - Map* map = heap->non_strict_arguments_elements_map(); + Handle map = + isolate()->factory()->non_strict_arguments_elements_map(); if (object->IsJSObject() && - Handle::cast(object)->elements()->map() == map) { + Handle::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 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(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 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. @@ -1996,19 +1976,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 function_handle(function, isolate); - CompileLazy(function_handle, CLEAR_EXCEPTION); - return *function_handle; -} - - // Used from ic-.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]); @@ -2017,39 +1987,40 @@ RUNTIME_FUNCTION(MaybeObject*, CallIC_Miss) { extra_ic_state, args.at(0), args.at(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 function(raw_function); + JSFunction::CompileLazy(function, CLEAR_EXCEPTION); + return *function; } // Used from ic-.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(0), args.at(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 function(raw_function); + JSFunction::CompileLazy(function, CLEAR_EXCEPTION); + return *function; } diff --git a/src/ic.h b/src/ic.h index fc302f8875..ba33e1d7f5 100644 --- a/src/ic.h +++ b/src/ic.h @@ -203,6 +203,7 @@ class CallICBase: public IC { : IC(EXTRA_CALL_FRAME, isolate), kind_(kind) {} public: + // Returns a JSFunction or a Failure. MUST_USE_RESULT MaybeObject* LoadFunction(State state, Code::ExtraICState extra_ic_state, Handle object, @@ -222,18 +223,18 @@ class CallICBase: public IC { Handle object, Handle name); - // Update the inline cache and the global stub cache based on the - // lookup result. + // Update the inline cache and the global stub cache based on the lookup + // result. void UpdateCaches(LookupResult* lookup, State state, Code::ExtraICState extra_ic_state, Handle object, Handle name); - // Returns a JSFunction if the object can be called as a function, - // and patches the stack to be ready for the call. - // Otherwise, it returns the undefined value. - Object* TryCallAsFunction(Object* object); + // Returns a JSFunction if the object can be called as a function, and + // patches the stack to be ready for the call. Otherwise, it returns the + // undefined value. + Handle TryCallAsFunction(Handle object); void ReceiverToObjectIfRequired(Handle callee, Handle object); diff --git a/src/objects.cc b/src/objects.cc index ee16ec4286..547cb730af 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -234,6 +234,14 @@ MaybeObject* JSProxy::GetPropertyWithHandler(Object* receiver_raw, } +Handle Object::GetElement(Handle object, uint32_t index) { + Isolate* isolate = object->IsHeapObject() + ? Handle::cast(object)->GetIsolate() + : Isolate::Current(); + CALL_HEAP_FUNCTION(isolate, object->GetElement(index), Object); +} + + MaybeObject* JSProxy::GetElementWithHandler(Object* receiver, uint32_t index) { String* name; @@ -528,12 +536,14 @@ bool JSObject::IsDirty() { } -Handle Object::GetProperty(Isolate* isolate, - Handle object, +Handle Object::GetProperty(Handle object, Handle receiver, LookupResult* result, Handle key, PropertyAttributes* attributes) { + Isolate* isolate = object->IsHeapObject() + ? Handle::cast(object)->GetIsolate() + : Isolate::Current(); CALL_HEAP_FUNCTION( isolate, object->GetProperty(*receiver, result, *key, attributes), @@ -6941,6 +6951,57 @@ void JSFunction::MarkForLazyRecompilation() { } +bool SharedFunctionInfo::EnsureCompiled(Handle 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 shared, + ClearExceptionFlag flag) { + CompilationInfo info(shared); + return CompileLazyHelper(&info, flag); +} + + +bool JSFunction::CompileLazy(Handle 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 function, + int osr_ast_id, + ClearExceptionFlag flag) { + CompilationInfo info(function); + info.SetOptimizing(osr_ast_id); + return CompileLazyHelper(&info, flag); +} + + bool JSFunction::IsInlineable() { if (IsBuiltin()) return false; SharedFunctionInfo* shared_info = shared(); diff --git a/src/objects.h b/src/objects.h index 5507c98290..24cde96548 100644 --- a/src/objects.h +++ b/src/objects.h @@ -913,8 +913,7 @@ class Object : public MaybeObject { String* key, PropertyAttributes* attributes); - static Handle GetProperty(Isolate* isolate, - Handle object, + static Handle GetProperty(Handle object, Handle receiver, LookupResult* result, Handle key, @@ -928,6 +927,7 @@ class Object : public MaybeObject { MUST_USE_RESULT MaybeObject* GetPropertyWithDefinedGetter(Object* receiver, JSReceiver* getter); + static Handle GetElement(Handle object, uint32_t index); inline MaybeObject* GetElement(uint32_t index); // For use when we know that no exception can be thrown. inline Object* GetElementNoExceptionThrown(uint32_t index); @@ -4917,6 +4917,13 @@ class SharedFunctionInfo: public HeapObject { void SharedFunctionInfoVerify(); #endif + // Helpers to compile the shared code. Returns true on success, false on + // failure (e.g., stack overflow during compilation). + static bool EnsureCompiled(Handle shared, + ClearExceptionFlag flag); + static bool CompileLazy(Handle shared, + ClearExceptionFlag flag); + // Casting. static inline SharedFunctionInfo* cast(Object* obj); @@ -5138,6 +5145,14 @@ class JSFunction: public JSObject { // recompiled the next time it is executed. void MarkForLazyRecompilation(); + // Helpers to compile this function. Returns true on success, false on + // failure (e.g., stack overflow during compilation). + static bool CompileLazy(Handle function, + ClearExceptionFlag flag); + static bool CompileOptimized(Handle function, + int osr_ast_id, + ClearExceptionFlag flag); + // Tells whether or not the function is already marked for lazy // recompilation. inline bool IsMarkedForLazyRecompilation(); diff --git a/src/runtime.cc b/src/runtime.cc index 03b15d4b0d..58b7512ace 100644 --- a/src/runtime.cc +++ b/src/runtime.cc @@ -1005,7 +1005,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOwnProperty) { case JSObject::INTERCEPTED_ELEMENT: case JSObject::FAST_ELEMENT: { elms->set(IS_ACCESSOR_INDEX, heap->false_value()); - Handle value = GetElement(obj, index); + Handle value = Object::GetElement(obj, index); RETURN_IF_EMPTY_HANDLE(isolate, value); elms->set(VALUE_INDEX, *value); elms->set(WRITABLE_INDEX, heap->true_value()); @@ -1049,7 +1049,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOwnProperty) { case NORMAL: { // This is a data property. elms->set(IS_ACCESSOR_INDEX, heap->false_value()); - Handle value = GetElement(obj, index); + Handle value = Object::GetElement(obj, index); ASSERT(!value.is_null()); elms->set(VALUE_INDEX, *value); elms->set(WRITABLE_INDEX, heap->ToBoolean(!details.IsReadOnly())); @@ -2110,7 +2110,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SetCode) { Handle fun = Handle::cast(code); Handle shared(fun->shared()); - if (!EnsureCompiled(shared, KEEP_EXCEPTION)) { + if (!SharedFunctionInfo::EnsureCompiled(shared, KEEP_EXCEPTION)) { return Failure::Exception(); } // 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 GetElement(object, index); -} - - -MaybeObject* Runtime::GetElement(Handle object, uint32_t index) { return object->GetElement(index); } @@ -8141,9 +8136,11 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NewObject) { // available. We cannot use EnsureCompiled because that forces a // compilation through the shared function info which makes it // impossible for us to optimize. - Handle shared(function->shared(), isolate); - if (!function->is_compiled()) CompileLazy(function, CLEAR_EXCEPTION); + if (!function->is_compiled()) { + JSFunction::CompileLazy(function, CLEAR_EXCEPTION); + } + Handle shared(function->shared(), isolate); if (!function->has_initial_map() && shared->IsInobjectSlackTrackingInProgress()) { // 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. ASSERT(!function->is_compiled()); - if (!CompileLazy(function, KEEP_EXCEPTION)) { + if (!JSFunction::CompileLazy(function, KEEP_EXCEPTION)) { return Failure::Exception(); } @@ -8231,7 +8228,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_LazyRecompile) { function->ReplaceCode(function->shared()->code()); return function->code(); } - if (CompileOptimized(function, AstNode::kNoNumber, CLEAR_EXCEPTION)) { + if (JSFunction::CompileOptimized(function, + AstNode::kNoNumber, + CLEAR_EXCEPTION)) { return function->code(); } if (FLAG_trace_opt) { @@ -8472,7 +8471,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CompileForOnStackReplacement) { // Try to compile the optimized code. A true return value from // CompileOptimized means that compilation succeeded, not necessarily // that optimization succeeded. - if (CompileOptimized(function, ast_id, CLEAR_EXCEPTION) && + if (JSFunction::CompileOptimized(function, ast_id, CLEAR_EXCEPTION) && function->IsOptimized()) { DeoptimizationInputData* data = DeoptimizationInputData::cast( function->code()->deoptimization_data()); @@ -9847,8 +9846,8 @@ static bool IterateElements(Isolate* isolate, } else if (receiver->HasElement(j)) { // Call GetElement on receiver, not its prototype, or getters won't // have the correct receiver. - element_value = GetElement(receiver, j); - if (element_value.is_null()) return false; + element_value = Object::GetElement(receiver, j); + RETURN_IF_EMPTY_HANDLE_VALUE(isolate, element_value, false); visitor->visit(j, element_value); } } @@ -9866,8 +9865,8 @@ static bool IterateElements(Isolate* isolate, while (j < n) { HandleScope loop_scope; uint32_t index = indices[j]; - Handle element = GetElement(receiver, index); - if (element.is_null()) return false; + Handle element = Object::GetElement(receiver, index); + RETURN_IF_EMPTY_HANDLE_VALUE(isolate, element, false); visitor->visit(index, element); // Skip to next different index (i.e., omit duplicates). do { @@ -10117,9 +10116,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SwapElements) { } Handle jsobject = Handle::cast(object); - Handle tmp1 = GetElement(jsobject, index1); + Handle tmp1 = Object::GetElement(jsobject, index1); RETURN_IF_EMPTY_HANDLE(isolate, tmp1); - Handle tmp2 = GetElement(jsobject, index2); + Handle tmp2 = Object::GetElement(jsobject, index2); RETURN_IF_EMPTY_HANDLE(isolate, tmp2); RETURN_IF_EMPTY_HANDLE(isolate, @@ -11629,7 +11628,7 @@ Object* Runtime::FindSharedFunctionInfoInScript(Isolate* isolate, if (!done) { // If the candidate is not compiled compile it to reveal any inner // functions which might contain the requested source position. - CompileLazyShared(target, KEEP_EXCEPTION); + SharedFunctionInfo::CompileLazy(target, KEEP_EXCEPTION); } } // End while loop. @@ -12376,7 +12375,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugDisassembleFunction) { // Get the function and make sure it is compiled. CONVERT_ARG_CHECKED(JSFunction, func, 0); Handle shared(func->shared()); - if (!EnsureCompiled(shared, KEEP_EXCEPTION)) { + if (!SharedFunctionInfo::EnsureCompiled(shared, KEEP_EXCEPTION)) { return Failure::Exception(); } func->code()->PrintLn(); @@ -12392,7 +12391,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugDisassembleConstructor) { // Get the function and make sure it is compiled. CONVERT_ARG_CHECKED(JSFunction, func, 0); Handle shared(func->shared()); - if (!EnsureCompiled(shared, KEEP_EXCEPTION)) { + if (!SharedFunctionInfo::EnsureCompiled(shared, KEEP_EXCEPTION)) { return Failure::Exception(); } shared->construct_stub()->PrintLn(); diff --git a/src/runtime.h b/src/runtime.h index 02f9d244b1..a369885580 100644 --- a/src/runtime.h +++ b/src/runtime.h @@ -626,16 +626,14 @@ class Runtime : public AllStatic { static bool IsUpperCaseChar(RuntimeState* runtime_state, uint16_t ch); - // TODO(1240886): The following three methods are *not* handle safe, - // but accept handle arguments. This seems fragile. + // TODO(1240886): Some of the following methods are *not* handle safe, but + // accept handle arguments. This seems fragile. // Support getting the characters in a string using [] notation as // in Firefox/SpiderMonkey, Safari and Opera. MUST_USE_RESULT static MaybeObject* GetElementOrCharAt(Isolate* isolate, Handle object, uint32_t index); - MUST_USE_RESULT static MaybeObject* GetElement(Handle object, - uint32_t index); MUST_USE_RESULT static MaybeObject* SetObjectProperty( Isolate* isolate, diff --git a/src/v8globals.h b/src/v8globals.h index ebbfd2b3f4..0601e8affb 100644 --- a/src/v8globals.h +++ b/src/v8globals.h @@ -557,6 +557,13 @@ enum VariableMode { // in a context }; + +enum ClearExceptionFlag { + KEEP_EXCEPTION, + CLEAR_EXCEPTION +}; + + } } // namespace v8::internal #endif // V8_V8GLOBALS_H_