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); |