| Index: src/runtime.cc
|
| diff --git a/src/runtime.cc b/src/runtime.cc
|
| index a514b946496fa5f46b0e251bed54efc1c7488abc..3c9a10dbfffe66f4b4579660ec8da1241f6ea717 100644
|
| --- a/src/runtime.cc
|
| +++ b/src/runtime.cc
|
| @@ -2166,7 +2166,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetReadOnlyPrototype) {
|
| // Construct a new field descriptor with updated attributes.
|
| DescriptorArray* instance_desc = function->map()->instance_descriptors();
|
|
|
| - int index = instance_desc->SearchWithCache(name, function->map());
|
| + int index = instance_desc->SearchWithCache(name);
|
| ASSERT(index != DescriptorArray::kNotFound);
|
| PropertyDetails details = instance_desc->GetDetails(index);
|
|
|
| @@ -5032,6 +5032,15 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_ToFastProperties) {
|
| }
|
|
|
|
|
| +RUNTIME_FUNCTION(MaybeObject*, Runtime_ToSlowProperties) {
|
| + ASSERT(args.length() == 1);
|
| + Object* obj = args[0];
|
| + return (obj->IsJSObject() && !obj->IsJSGlobalProxy())
|
| + ? JSObject::cast(obj)->NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0)
|
| + : obj;
|
| +}
|
| +
|
| +
|
| RUNTIME_FUNCTION(MaybeObject*, Runtime_ToBool) {
|
| NoHandleAllocation ha;
|
| ASSERT(args.length() == 1);
|
| @@ -7900,8 +7909,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_LazyRecompile) {
|
|
|
| // If the function is not optimizable or debugger is active continue using the
|
| // code from the full compiler.
|
| - if (!FLAG_crankshaft ||
|
| - !function->shared()->code()->optimizable() ||
|
| + if (!function->shared()->code()->optimizable() ||
|
| isolate->DebuggerHasBreakPoints()) {
|
| if (FLAG_trace_opt) {
|
| PrintF("[failed to optimize ");
|
| @@ -7962,6 +7970,35 @@ class ActivationsFinder : public ThreadVisitor {
|
| };
|
|
|
|
|
| +static void MaterializeArgumentsObjectInFrame(Isolate* isolate,
|
| + JavaScriptFrame* frame) {
|
| + Handle<JSFunction> function(JSFunction::cast(frame->function()), isolate);
|
| + Handle<Object> arguments;
|
| + for (int i = frame->ComputeExpressionsCount() - 1; i >= 0; --i) {
|
| + if (frame->GetExpression(i) == isolate->heap()->arguments_marker()) {
|
| + if (arguments.is_null()) {
|
| + // FunctionGetArguments can't throw an exception, so cast away the
|
| + // doubt with an assert.
|
| + arguments = Handle<Object>(
|
| + Accessors::FunctionGetArguments(*function,
|
| + NULL)->ToObjectUnchecked());
|
| + ASSERT(*arguments != isolate->heap()->null_value());
|
| + ASSERT(*arguments != isolate->heap()->undefined_value());
|
| + }
|
| + frame->SetExpression(i, *arguments);
|
| + if (FLAG_trace_deopt) {
|
| + PrintF("Materializing arguments object for frame %p - %p: %p ",
|
| + reinterpret_cast<void*>(frame->sp()),
|
| + reinterpret_cast<void*>(frame->fp()),
|
| + reinterpret_cast<void*>(*arguments));
|
| + arguments->ShortPrint();
|
| + PrintF("\n");
|
| + }
|
| + }
|
| + }
|
| +}
|
| +
|
| +
|
| RUNTIME_FUNCTION(MaybeObject*, Runtime_NotifyDeoptimized) {
|
| HandleScope scope(isolate);
|
| ASSERT(args.length() == 1);
|
| @@ -7970,16 +8007,25 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NotifyDeoptimized) {
|
| static_cast<Deoptimizer::BailoutType>(args.smi_at(0));
|
| Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate);
|
| ASSERT(isolate->heap()->IsAllocationAllowed());
|
| - JavaScriptFrameIterator it(isolate);
|
| + int jsframes = deoptimizer->jsframe_count();
|
|
|
| - // Make sure to materialize objects before causing any allocation.
|
| - deoptimizer->MaterializeHeapObjects(&it);
|
| + deoptimizer->MaterializeHeapNumbers();
|
| delete deoptimizer;
|
|
|
| + JavaScriptFrameIterator it(isolate);
|
| + for (int i = 0; i < jsframes - 1; i++) {
|
| + MaterializeArgumentsObjectInFrame(isolate, it.frame());
|
| + it.Advance();
|
| + }
|
| +
|
| JavaScriptFrame* frame = it.frame();
|
| RUNTIME_ASSERT(frame->function()->IsJSFunction());
|
| Handle<JSFunction> function(JSFunction::cast(frame->function()), isolate);
|
| - RUNTIME_ASSERT(type != Deoptimizer::EAGER || function->IsOptimized());
|
| + MaterializeArgumentsObjectInFrame(isolate, frame);
|
| +
|
| + if (type == Deoptimizer::EAGER) {
|
| + RUNTIME_ASSERT(function->IsOptimized());
|
| + }
|
|
|
| // Avoid doing too much work when running with --always-opt and keep
|
| // the optimized code around.
|
| @@ -9052,10 +9098,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CompileString) {
|
| // strings. Throw an exception if it doesn't.
|
| if (context->allow_code_gen_from_strings()->IsFalse() &&
|
| !CodeGenerationFromStringsAllowed(isolate, context)) {
|
| - Handle<Object> error_message =
|
| - context->ErrorMessageForCodeGenerationFromStrings();
|
| - return isolate->Throw(*isolate->factory()->NewEvalError(
|
| - "code_gen_from_strings", HandleVector<Object>(&error_message, 1)));
|
| + return isolate->Throw(*isolate->factory()->NewError(
|
| + "code_gen_from_strings", HandleVector<Object>(NULL, 0)));
|
| }
|
|
|
| // Compile source string in the native context.
|
| @@ -9082,10 +9126,8 @@ static ObjectPair CompileGlobalEval(Isolate* isolate,
|
| // strings. Throw an exception if it doesn't.
|
| if (native_context->allow_code_gen_from_strings()->IsFalse() &&
|
| !CodeGenerationFromStringsAllowed(isolate, native_context)) {
|
| - Handle<Object> error_message =
|
| - context->ErrorMessageForCodeGenerationFromStrings();
|
| - isolate->Throw(*isolate->factory()->NewEvalError(
|
| - "code_gen_from_strings", HandleVector<Object>(&error_message, 1)));
|
| + isolate->Throw(*isolate->factory()->NewError(
|
| + "code_gen_from_strings", HandleVector<Object>(NULL, 0)));
|
| return MakePair(Failure::Exception(), NULL);
|
| }
|
|
|
| @@ -10838,8 +10880,7 @@ class ScopeIterator {
|
| inlined_jsframe_index_(inlined_jsframe_index),
|
| function_(JSFunction::cast(frame->function())),
|
| context_(Context::cast(frame->context())),
|
| - nested_scope_chain_(4),
|
| - failed_(false) {
|
| + nested_scope_chain_(4) {
|
|
|
| // Catch the case when the debugger stops in an internal function.
|
| Handle<SharedFunctionInfo> shared_info(function_->shared());
|
| @@ -10913,24 +10954,17 @@ class ScopeIterator {
|
| frame_(NULL),
|
| inlined_jsframe_index_(0),
|
| function_(function),
|
| - context_(function->context()),
|
| - failed_(false) {
|
| + context_(function->context()) {
|
| if (function->IsBuiltin()) {
|
| context_ = Handle<Context>();
|
| }
|
| }
|
|
|
| // More scopes?
|
| - bool Done() {
|
| - ASSERT(!failed_);
|
| - return context_.is_null();
|
| - }
|
| -
|
| - bool Failed() { return failed_; }
|
| + bool Done() { return context_.is_null(); }
|
|
|
| // Move to the next scope.
|
| void Next() {
|
| - ASSERT(!failed_);
|
| ScopeType scope_type = Type();
|
| if (scope_type == ScopeTypeGlobal) {
|
| // The global scope is always the last in the chain.
|
| @@ -10951,7 +10985,6 @@ class ScopeIterator {
|
|
|
| // Return the type of the current scope.
|
| ScopeType Type() {
|
| - ASSERT(!failed_);
|
| if (!nested_scope_chain_.is_empty()) {
|
| Handle<ScopeInfo> scope_info = nested_scope_chain_.last();
|
| switch (scope_info->Type()) {
|
| @@ -11001,7 +11034,6 @@ class ScopeIterator {
|
|
|
| // Return the JavaScript object with the content of the current scope.
|
| Handle<JSObject> ScopeObject() {
|
| - ASSERT(!failed_);
|
| switch (Type()) {
|
| case ScopeIterator::ScopeTypeGlobal:
|
| return Handle<JSObject>(CurrentContext()->global_object());
|
| @@ -11027,7 +11059,6 @@ class ScopeIterator {
|
| }
|
|
|
| Handle<ScopeInfo> CurrentScopeInfo() {
|
| - ASSERT(!failed_);
|
| if (!nested_scope_chain_.is_empty()) {
|
| return nested_scope_chain_.last();
|
| } else if (context_->IsBlockContext()) {
|
| @@ -11041,7 +11072,6 @@ class ScopeIterator {
|
| // Return the context for this scope. For the local context there might not
|
| // be an actual context.
|
| Handle<Context> CurrentContext() {
|
| - ASSERT(!failed_);
|
| if (Type() == ScopeTypeGlobal ||
|
| nested_scope_chain_.is_empty()) {
|
| return context_;
|
| @@ -11055,7 +11085,6 @@ class ScopeIterator {
|
| #ifdef DEBUG
|
| // Debug print of the content of the current scope.
|
| void DebugPrint() {
|
| - ASSERT(!failed_);
|
| switch (Type()) {
|
| case ScopeIterator::ScopeTypeGlobal:
|
| PrintF("Global:\n");
|
| @@ -11113,7 +11142,6 @@ class ScopeIterator {
|
| Handle<JSFunction> function_;
|
| Handle<Context> context_;
|
| List<Handle<ScopeInfo> > nested_scope_chain_;
|
| - bool failed_;
|
|
|
| void RetrieveScopeChain(Scope* scope,
|
| Handle<SharedFunctionInfo> shared_info) {
|
| @@ -11126,9 +11154,7 @@ class ScopeIterator {
|
| // faulty. We fail in debug mode but in release mode we only provide the
|
| // information we get from the context chain but nothing about
|
| // completely stack allocated scopes or stack allocated locals.
|
| - // Or it could be due to stack overflow.
|
| - ASSERT(isolate_->has_pending_exception());
|
| - failed_ = true;
|
| + UNREACHABLE();
|
| }
|
| }
|
|
|
| @@ -11553,8 +11579,6 @@ static Handle<Context> CopyNestedScopeContextChain(Isolate* isolate,
|
| List<Handle<Context> > context_chain;
|
|
|
| ScopeIterator it(isolate, frame, inlined_jsframe_index);
|
| - if (it.Failed()) return Handle<Context>::null();
|
| -
|
| for (; it.Type() != ScopeIterator::ScopeTypeGlobal &&
|
| it.Type() != ScopeIterator::ScopeTypeLocal ; it.Next()) {
|
| ASSERT(!it.Done());
|
| @@ -11583,7 +11607,9 @@ static Handle<Context> CopyNestedScopeContextChain(Isolate* isolate,
|
| // Materialize the contents of the block scope into a JSObject.
|
| Handle<JSObject> block_scope_object =
|
| MaterializeBlockScope(isolate, current);
|
| - CHECK(!block_scope_object.is_null());
|
| + if (block_scope_object.is_null()) {
|
| + return Handle<Context>::null();
|
| + }
|
| // Allocate a new function context for the debug evaluation and set the
|
| // extension object.
|
| Handle<Context> new_context =
|
| @@ -11744,12 +11770,6 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) {
|
| context,
|
| frame,
|
| inlined_jsframe_index);
|
| - if (context.is_null()) {
|
| - ASSERT(isolate->has_pending_exception());
|
| - MaybeObject* exception = isolate->pending_exception();
|
| - isolate->clear_pending_exception();
|
| - return exception;
|
| - }
|
|
|
| if (additional_context->IsJSObject()) {
|
| Handle<JSObject> extension = Handle<JSObject>::cast(additional_context);
|
|
|