Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(26)

Side by Side Diff: src/runtime.cc

Issue 7343005: Support scope information and evaluation in optimized frames (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 10006 matching lines...) Expand 10 before | Expand all | Expand 10 after
10017 CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]); 10017 CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
10018 Heap* heap = isolate->heap(); 10018 Heap* heap = isolate->heap();
10019 10019
10020 // Find the relevant frame with the requested index. 10020 // Find the relevant frame with the requested index.
10021 StackFrame::Id id = isolate->debug()->break_frame_id(); 10021 StackFrame::Id id = isolate->debug()->break_frame_id();
10022 if (id == StackFrame::NO_ID) { 10022 if (id == StackFrame::NO_ID) {
10023 // If there are no JavaScript stack frames return undefined. 10023 // If there are no JavaScript stack frames return undefined.
10024 return heap->undefined_value(); 10024 return heap->undefined_value();
10025 } 10025 }
10026 10026
10027 int deoptimized_frame_index = -1; // Frame index in optimized frame. 10027 int inlined_frame_index = 0; // Inlined frame index in optimized frame.
10028 DeoptimizedFrameInfo* deoptimized_frame = NULL;
10029 10028
10030 int count = 0; 10029 int count = 0;
10031 JavaScriptFrameIterator it(isolate, id); 10030 JavaScriptFrameIterator it(isolate, id);
10032 for (; !it.done(); it.Advance()) { 10031 for (; !it.done(); it.Advance()) {
10033 if (index < count + it.frame()->GetInlineCount()) break; 10032 if (index < count + it.frame()->GetInlineCount()) break;
10034 count += it.frame()->GetInlineCount(); 10033 count += it.frame()->GetInlineCount();
10035 } 10034 }
10036 if (it.done()) return heap->undefined_value(); 10035 if (it.done()) return heap->undefined_value();
10037 10036
10038 if (it.frame()->is_optimized()) { 10037 if (it.frame()->is_optimized()) {
10039 deoptimized_frame_index = 10038 inlined_frame_index =
10040 it.frame()->GetInlineCount() - (index - count) - 1; 10039 it.frame()->GetInlineCount() - (index - count) - 1;
10041 deoptimized_frame = Deoptimizer::DebuggerInspectableFrame(
10042 it.frame(),
10043 deoptimized_frame_index,
10044 isolate);
10045 } 10040 }
10041 ScopedDeoptimizedFrameInfo deoptimized_frame(
10042 it.frame(), inlined_frame_index, isolate);
10046 10043
10047 // Traverse the saved contexts chain to find the active context for the 10044 // Traverse the saved contexts chain to find the active context for the
10048 // selected frame. 10045 // selected frame.
10049 SaveContext* save = isolate->save_context(); 10046 SaveContext* save = isolate->save_context();
10050 while (save != NULL && !save->below(it.frame())) { 10047 while (save != NULL && !save->below(it.frame())) {
10051 save = save->prev(); 10048 save = save->prev();
10052 } 10049 }
10053 ASSERT(save != NULL); 10050 ASSERT(save != NULL);
10054 10051
10055 // Get the frame id. 10052 // Get the frame id.
10056 Handle<Object> frame_id(WrapFrameId(it.frame()->id()), isolate); 10053 Handle<Object> frame_id(WrapFrameId(it.frame()->id()), isolate);
10057 10054
10058 // Find source position. 10055 // Find source position.
10059 int position = 10056 int position =
10060 it.frame()->LookupCode()->SourcePosition(it.frame()->pc()); 10057 it.frame()->LookupCode()->SourcePosition(it.frame()->pc());
10061 10058
10062 // Check for constructor frame. Inlined frames cannot be construct calls. 10059 // Check for constructor frame. Inlined frames cannot be construct calls.
10063 bool inlined_frame = 10060 bool inlined_frame =
10064 it.frame()->is_optimized() && deoptimized_frame_index != 0; 10061 it.frame()->is_optimized() && inlined_frame_index != 0;
10065 bool constructor = !inlined_frame && it.frame()->IsConstructor(); 10062 bool constructor = !inlined_frame && it.frame()->IsConstructor();
10066 10063
10067 // Get scope info and read from it for local variable information. 10064 // Get scope info and read from it for local variable information.
10068 Handle<JSFunction> function(JSFunction::cast(it.frame()->function())); 10065 Handle<JSFunction> function(JSFunction::cast(it.frame()->function()));
10069 Handle<SerializedScopeInfo> scope_info(function->shared()->scope_info()); 10066 Handle<SerializedScopeInfo> scope_info(function->shared()->scope_info());
10070 ASSERT(*scope_info != SerializedScopeInfo::Empty()); 10067 ASSERT(*scope_info != SerializedScopeInfo::Empty());
10071 ScopeInfo<> info(*scope_info); 10068 ScopeInfo<> info(*scope_info);
10072 10069
10073 // Get the locals names and values into a temporary array. 10070 // Get the locals names and values into a temporary array.
10074 // 10071 //
10075 // TODO(1240907): Hide compiler-introduced stack variables 10072 // TODO(1240907): Hide compiler-introduced stack variables
10076 // (e.g. .result)? For users of the debugger, they will probably be 10073 // (e.g. .result)? For users of the debugger, they will probably be
10077 // confusing. 10074 // confusing.
10078 Handle<FixedArray> locals = 10075 Handle<FixedArray> locals =
10079 isolate->factory()->NewFixedArray(info.NumberOfLocals() * 2); 10076 isolate->factory()->NewFixedArray(info.NumberOfLocals() * 2);
10080 10077
10081 // Fill in the values of the locals. 10078 // Fill in the values of the locals.
10082 int i = 0; 10079 int i = 0;
10083 for (; i < info.number_of_stack_slots(); ++i) { 10080 for (; i < info.number_of_stack_slots(); ++i) {
10084 // Use the value from the stack. 10081 // Use the value from the stack.
10085 locals->set(i * 2, *info.LocalName(i)); 10082 locals->set(i * 2, *info.LocalName(i));
10086 if (it.frame()->is_optimized()) { 10083 if (it.frame()->is_optimized()) {
10087 // Get the value from the deoptimized frame. 10084 // Get the value from the deoptimized frame.
10088 locals->set(i * 2 + 1, 10085 locals->set(i * 2 + 1,
10089 deoptimized_frame->GetExpression(i)); 10086 deoptimized_frame.GetExpression(i));
10090 } else { 10087 } else {
10091 // Get the value from the stack. 10088 // Get the value from the stack.
10092 locals->set(i * 2 + 1, it.frame()->GetExpression(i)); 10089 locals->set(i * 2 + 1, it.frame()->GetExpression(i));
10093 } 10090 }
10094 } 10091 }
10095 if (i < info.NumberOfLocals()) { 10092 if (i < info.NumberOfLocals()) {
10096 // Get the context containing declarations. 10093 // Get the context containing declarations.
10097 Handle<Context> context( 10094 Handle<Context> context(
10098 Context::cast(it.frame()->context())->declaration_context()); 10095 Context::cast(it.frame()->context())->declaration_context());
10099 for (; i < info.NumberOfLocals(); ++i) { 10096 for (; i < info.NumberOfLocals(); ++i) {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
10146 // Now advance to the arguments adapter frame (if any). It contains all 10143 // Now advance to the arguments adapter frame (if any). It contains all
10147 // the provided parameters whereas the function frame always have the number 10144 // the provided parameters whereas the function frame always have the number
10148 // of arguments matching the functions parameters. The rest of the 10145 // of arguments matching the functions parameters. The rest of the
10149 // information (except for what is collected above) is the same. 10146 // information (except for what is collected above) is the same.
10150 it.AdvanceToArgumentsFrame(); 10147 it.AdvanceToArgumentsFrame();
10151 10148
10152 // Find the number of arguments to fill. At least fill the number of 10149 // Find the number of arguments to fill. At least fill the number of
10153 // parameters for the function and fill more if more parameters are provided. 10150 // parameters for the function and fill more if more parameters are provided.
10154 int argument_count = info.number_of_parameters(); 10151 int argument_count = info.number_of_parameters();
10155 if (it.frame()->is_optimized()) { 10152 if (it.frame()->is_optimized()) {
10156 ASSERT_EQ(argument_count, deoptimized_frame->parameters_count()); 10153 ASSERT_EQ(argument_count, deoptimized_frame.parameters_count());
10157 } else { 10154 } else {
10158 if (argument_count < it.frame()->ComputeParametersCount()) { 10155 if (argument_count < it.frame()->ComputeParametersCount()) {
10159 argument_count = it.frame()->ComputeParametersCount(); 10156 argument_count = it.frame()->ComputeParametersCount();
10160 } 10157 }
10161 } 10158 }
10162 10159
10163 // Calculate the size of the result. 10160 // Calculate the size of the result.
10164 int details_size = kFrameDetailsFirstDynamicIndex + 10161 int details_size = kFrameDetailsFirstDynamicIndex +
10165 2 * (argument_count + info.NumberOfLocals()) + 10162 2 * (argument_count + info.NumberOfLocals()) +
10166 (at_return ? 1 : 0); 10163 (at_return ? 1 : 0);
10167 Handle<FixedArray> details = isolate->factory()->NewFixedArray(details_size); 10164 Handle<FixedArray> details = isolate->factory()->NewFixedArray(details_size);
10168 10165
10169 // Add the frame id. 10166 // Add the frame id.
10170 details->set(kFrameDetailsFrameIdIndex, *frame_id); 10167 details->set(kFrameDetailsFrameIdIndex, *frame_id);
10171 10168
10172 // Add the function (same as in function frame). 10169 // Add the function (same as in function frame).
10173 if (it.frame()->is_optimized()) { 10170 if (it.frame()->is_optimized()) {
10174 // Get the function from the deoptimized frame. 10171 // Get the function from the deoptimized frame.
10175 details->set(kFrameDetailsFunctionIndex, deoptimized_frame->GetFunction()); 10172 details->set(kFrameDetailsFunctionIndex, deoptimized_frame.GetFunction());
10176 } else { 10173 } else {
10177 // Get the function from the stack. 10174 // Get the function from the stack.
10178 details->set(kFrameDetailsFunctionIndex, it.frame()->function()); 10175 details->set(kFrameDetailsFunctionIndex, it.frame()->function());
10179 } 10176 }
10180 10177
10181 // Add the arguments count. 10178 // Add the arguments count.
10182 details->set(kFrameDetailsArgumentCountIndex, Smi::FromInt(argument_count)); 10179 details->set(kFrameDetailsArgumentCountIndex, Smi::FromInt(argument_count));
10183 10180
10184 // Add the locals count 10181 // Add the locals count
10185 details->set(kFrameDetailsLocalCountIndex, 10182 details->set(kFrameDetailsLocalCountIndex,
(...skipping 15 matching lines...) Expand all
10201 // Add flags to indicate information on whether this frame is 10198 // Add flags to indicate information on whether this frame is
10202 // bit 0: invoked in the debugger context. 10199 // bit 0: invoked in the debugger context.
10203 // bit 1: optimized frame. 10200 // bit 1: optimized frame.
10204 // bit 2: inlined in optimized frame 10201 // bit 2: inlined in optimized frame
10205 int flags = 0; 10202 int flags = 0;
10206 if (*save->context() == *isolate->debug()->debug_context()) { 10203 if (*save->context() == *isolate->debug()->debug_context()) {
10207 flags |= 1 << 0; 10204 flags |= 1 << 0;
10208 } 10205 }
10209 if (it.frame()->is_optimized()) { 10206 if (it.frame()->is_optimized()) {
10210 flags |= 1 << 1; 10207 flags |= 1 << 1;
10211 if (deoptimized_frame_index > 0) { 10208 flags |= inlined_frame_index << 2;
10212 flags |= 1 << 2;
10213 }
10214 } 10209 }
10215 details->set(kFrameDetailsFlagsIndex, Smi::FromInt(flags)); 10210 details->set(kFrameDetailsFlagsIndex, Smi::FromInt(flags));
10216 10211
10217 // Fill the dynamic part. 10212 // Fill the dynamic part.
10218 int details_index = kFrameDetailsFirstDynamicIndex; 10213 int details_index = kFrameDetailsFirstDynamicIndex;
10219 10214
10220 // Add arguments name and value. 10215 // Add arguments name and value.
10221 for (int i = 0; i < argument_count; i++) { 10216 for (int i = 0; i < argument_count; i++) {
10222 // Name of the argument. 10217 // Name of the argument.
10223 if (i < info.number_of_parameters()) { 10218 if (i < info.number_of_parameters()) {
10224 details->set(details_index++, *info.parameter_name(i)); 10219 details->set(details_index++, *info.parameter_name(i));
10225 } else { 10220 } else {
10226 details->set(details_index++, heap->undefined_value()); 10221 details->set(details_index++, heap->undefined_value());
10227 } 10222 }
10228 10223
10229 // Parameter value. 10224 // Parameter value.
10230 if (it.frame()->is_optimized()) { 10225 if (it.frame()->is_optimized()) {
10231 // Get the value from the deoptimized frame. 10226 // Get the value from the deoptimized frame.
10232 details->set(details_index++, deoptimized_frame->GetParameter(i)); 10227 details->set(details_index++, deoptimized_frame.GetParameter(i));
10233 } else { 10228 } else {
10234 if (i < it.frame()->ComputeParametersCount()) { 10229 if (i < it.frame()->ComputeParametersCount()) {
10235 // Get the value from the stack. 10230 // Get the value from the stack.
10236 details->set(details_index++, it.frame()->GetParameter(i)); 10231 details->set(details_index++, it.frame()->GetParameter(i));
10237 } else { 10232 } else {
10238 details->set(details_index++, heap->undefined_value()); 10233 details->set(details_index++, heap->undefined_value());
10239 } 10234 }
10240 } 10235 }
10241 } 10236 }
10242 10237
(...skipping 18 matching lines...) Expand all
10261 // by creating correct wrapper object based on the calling frame's 10256 // by creating correct wrapper object based on the calling frame's
10262 // global context. 10257 // global context.
10263 it.Advance(); 10258 it.Advance();
10264 Handle<Context> calling_frames_global_context( 10259 Handle<Context> calling_frames_global_context(
10265 Context::cast(Context::cast(it.frame()->context())->global_context())); 10260 Context::cast(Context::cast(it.frame()->context())->global_context()));
10266 receiver = 10261 receiver =
10267 isolate->factory()->ToObject(receiver, calling_frames_global_context); 10262 isolate->factory()->ToObject(receiver, calling_frames_global_context);
10268 } 10263 }
10269 details->set(kFrameDetailsReceiverIndex, *receiver); 10264 details->set(kFrameDetailsReceiverIndex, *receiver);
10270 10265
10271 // Get rid of the calculated deoptimized frame if any.
10272 if (deoptimized_frame != NULL) {
10273 Deoptimizer::DeleteDebuggerInspectableFrame(deoptimized_frame,
10274 isolate);
10275 }
10276
10277 ASSERT_EQ(details_size, details_index); 10266 ASSERT_EQ(details_size, details_index);
10278 return *isolate->factory()->NewJSArrayWithElements(details); 10267 return *isolate->factory()->NewJSArrayWithElements(details);
10279 } 10268 }
10280 10269
10281 10270
10282 // Copy all the context locals into an object used to materialize a scope. 10271 // Copy all the context locals into an object used to materialize a scope.
10283 static bool CopyContextLocalsToScopeObject( 10272 static bool CopyContextLocalsToScopeObject(
10284 Isolate* isolate, 10273 Isolate* isolate,
10285 Handle<SerializedScopeInfo> serialized_scope_info, 10274 Handle<SerializedScopeInfo> serialized_scope_info,
10286 ScopeInfo<>& scope_info, 10275 ScopeInfo<>& scope_info,
(...skipping 15 matching lines...) Expand all
10302 kNonStrictMode), 10291 kNonStrictMode),
10303 false); 10292 false);
10304 } 10293 }
10305 10294
10306 return true; 10295 return true;
10307 } 10296 }
10308 10297
10309 10298
10310 // Create a plain JSObject which materializes the local scope for the specified 10299 // Create a plain JSObject which materializes the local scope for the specified
10311 // frame. 10300 // frame.
10312 static Handle<JSObject> MaterializeLocalScope(Isolate* isolate, 10301 static Handle<JSObject> MaterializeLocalScope(
10313 JavaScriptFrame* frame) { 10302 Isolate* isolate,
10303 JavaScriptFrame* frame,
10304 int inlined_frame_index) {
10314 Handle<JSFunction> function(JSFunction::cast(frame->function())); 10305 Handle<JSFunction> function(JSFunction::cast(frame->function()));
10315 Handle<SharedFunctionInfo> shared(function->shared()); 10306 Handle<SharedFunctionInfo> shared(function->shared());
10316 Handle<SerializedScopeInfo> serialized_scope_info(shared->scope_info()); 10307 Handle<SerializedScopeInfo> serialized_scope_info(shared->scope_info());
10317 ScopeInfo<> scope_info(*serialized_scope_info); 10308 ScopeInfo<> scope_info(*serialized_scope_info);
10309 ScopedDeoptimizedFrameInfo deoptimized_frame(
10310 frame, inlined_frame_index, isolate);
10318 10311
10319 // Allocate and initialize a JSObject with all the arguments, stack locals 10312 // Allocate and initialize a JSObject with all the arguments, stack locals
10320 // heap locals and extension properties of the debugged function. 10313 // heap locals and extension properties of the debugged function.
10321 Handle<JSObject> local_scope = 10314 Handle<JSObject> local_scope =
10322 isolate->factory()->NewJSObject(isolate->object_function()); 10315 isolate->factory()->NewJSObject(isolate->object_function());
10323 10316
10324 // First fill all parameters. 10317 // First fill all parameters.
10325 for (int i = 0; i < scope_info.number_of_parameters(); ++i) { 10318 for (int i = 0; i < scope_info.number_of_parameters(); ++i) {
10319 Handle<Object> parameter;
10320 if (frame->is_optimized()) {
10321 parameter = Handle<Object>(deoptimized_frame.GetParameter(i));
10322 } else {
10323 parameter = Handle<Object>(frame->GetParameter(i));
10324 }
10326 RETURN_IF_EMPTY_HANDLE_VALUE( 10325 RETURN_IF_EMPTY_HANDLE_VALUE(
10327 isolate, 10326 isolate,
10328 SetProperty(local_scope, 10327 SetProperty(local_scope,
10329 scope_info.parameter_name(i), 10328 scope_info.parameter_name(i),
10330 Handle<Object>(frame->GetParameter(i), isolate), 10329 parameter,
10331 NONE, 10330 NONE,
10332 kNonStrictMode), 10331 kNonStrictMode),
10333 Handle<JSObject>()); 10332 Handle<JSObject>());
10334 } 10333 }
10335 10334
10336 // Second fill all stack locals. 10335 // Second fill all stack locals.
10337 for (int i = 0; i < scope_info.number_of_stack_slots(); ++i) { 10336 for (int i = 0; i < scope_info.number_of_stack_slots(); ++i) {
10337 Handle<Object> expression;
10338 if (frame->is_optimized()) {
10339 expression = Handle<Object>(deoptimized_frame.GetExpression(i));
10340 } else {
10341 expression = Handle<Object>(frame->GetExpression(i));
10342 }
10338 RETURN_IF_EMPTY_HANDLE_VALUE( 10343 RETURN_IF_EMPTY_HANDLE_VALUE(
10339 isolate, 10344 isolate,
10340 SetProperty(local_scope, 10345 SetProperty(local_scope,
10341 scope_info.stack_slot_name(i), 10346 scope_info.stack_slot_name(i),
10342 Handle<Object>(frame->GetExpression(i), isolate), 10347 expression,
10343 NONE, 10348 NONE,
10344 kNonStrictMode), 10349 kNonStrictMode),
10345 Handle<JSObject>()); 10350 Handle<JSObject>());
10346 } 10351 }
10347 10352
10348 if (scope_info.number_of_context_slots() > Context::MIN_CONTEXT_SLOTS) { 10353 if (scope_info.number_of_context_slots() > Context::MIN_CONTEXT_SLOTS) {
10349 // Third fill all context locals. 10354 // Third fill all context locals.
10350 Handle<Context> frame_context(Context::cast(frame->context())); 10355 Handle<Context> frame_context(Context::cast(frame->context()));
10351 Handle<Context> function_context(frame_context->declaration_context()); 10356 Handle<Context> function_context(frame_context->declaration_context());
10352 if (!CopyContextLocalsToScopeObject(isolate, 10357 if (!CopyContextLocalsToScopeObject(isolate,
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
10452 class ScopeIterator { 10457 class ScopeIterator {
10453 public: 10458 public:
10454 enum ScopeType { 10459 enum ScopeType {
10455 ScopeTypeGlobal = 0, 10460 ScopeTypeGlobal = 0,
10456 ScopeTypeLocal, 10461 ScopeTypeLocal,
10457 ScopeTypeWith, 10462 ScopeTypeWith,
10458 ScopeTypeClosure, 10463 ScopeTypeClosure,
10459 ScopeTypeCatch 10464 ScopeTypeCatch
10460 }; 10465 };
10461 10466
10462 ScopeIterator(Isolate* isolate, JavaScriptFrame* frame) 10467 ScopeIterator(Isolate* isolate,
10468 JavaScriptFrame* frame,
10469 int inlined_frame_index)
10463 : isolate_(isolate), 10470 : isolate_(isolate),
10464 frame_(frame), 10471 frame_(frame),
10472 inlined_frame_index_(inlined_frame_index),
10465 function_(JSFunction::cast(frame->function())), 10473 function_(JSFunction::cast(frame->function())),
10466 context_(Context::cast(frame->context())), 10474 context_(Context::cast(frame->context())),
10467 local_done_(false), 10475 local_done_(false),
10468 at_local_(false) { 10476 at_local_(false) {
10469 10477
10470 // Check whether the first scope is actually a local scope. 10478 // Check whether the first scope is actually a local scope.
10471 if (context_->IsGlobalContext()) { 10479 if (context_->IsGlobalContext()) {
10472 // If there is a stack slot for .result then this local scope has been 10480 // If there is a stack slot for .result then this local scope has been
10473 // created for evaluating top level code and it is not a real local scope. 10481 // created for evaluating top level code and it is not a real local scope.
10474 // Checking for the existence of .result seems fragile, but the scope info 10482 // Checking for the existence of .result seems fragile, but the scope info
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
10539 return ScopeTypeWith; 10547 return ScopeTypeWith;
10540 } 10548 }
10541 10549
10542 // Return the JavaScript object with the content of the current scope. 10550 // Return the JavaScript object with the content of the current scope.
10543 Handle<JSObject> ScopeObject() { 10551 Handle<JSObject> ScopeObject() {
10544 switch (Type()) { 10552 switch (Type()) {
10545 case ScopeIterator::ScopeTypeGlobal: 10553 case ScopeIterator::ScopeTypeGlobal:
10546 return Handle<JSObject>(CurrentContext()->global()); 10554 return Handle<JSObject>(CurrentContext()->global());
10547 case ScopeIterator::ScopeTypeLocal: 10555 case ScopeIterator::ScopeTypeLocal:
10548 // Materialize the content of the local scope into a JSObject. 10556 // Materialize the content of the local scope into a JSObject.
10549 return MaterializeLocalScope(isolate_, frame_); 10557 return MaterializeLocalScope(isolate_, frame_, inlined_frame_index_);
10550 case ScopeIterator::ScopeTypeWith: 10558 case ScopeIterator::ScopeTypeWith:
10551 // Return the with object. 10559 // Return the with object.
10552 return Handle<JSObject>(JSObject::cast(CurrentContext()->extension())); 10560 return Handle<JSObject>(JSObject::cast(CurrentContext()->extension()));
10553 case ScopeIterator::ScopeTypeCatch: 10561 case ScopeIterator::ScopeTypeCatch:
10554 return MaterializeCatchScope(isolate_, CurrentContext()); 10562 return MaterializeCatchScope(isolate_, CurrentContext());
10555 case ScopeIterator::ScopeTypeClosure: 10563 case ScopeIterator::ScopeTypeClosure:
10556 // Materialize the content of the closure scope into a JSObject. 10564 // Materialize the content of the closure scope into a JSObject.
10557 return MaterializeClosure(isolate_, CurrentContext()); 10565 return MaterializeClosure(isolate_, CurrentContext());
10558 } 10566 }
10559 UNREACHABLE(); 10567 UNREACHABLE();
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
10619 default: 10627 default:
10620 UNREACHABLE(); 10628 UNREACHABLE();
10621 } 10629 }
10622 PrintF("\n"); 10630 PrintF("\n");
10623 } 10631 }
10624 #endif 10632 #endif
10625 10633
10626 private: 10634 private:
10627 Isolate* isolate_; 10635 Isolate* isolate_;
10628 JavaScriptFrame* frame_; 10636 JavaScriptFrame* frame_;
10637 int inlined_frame_index_;
10629 Handle<JSFunction> function_; 10638 Handle<JSFunction> function_;
10630 Handle<Context> context_; 10639 Handle<Context> context_;
10631 bool local_done_; 10640 bool local_done_;
10632 bool at_local_; 10641 bool at_local_;
10633 10642
10634 DISALLOW_IMPLICIT_CONSTRUCTORS(ScopeIterator); 10643 DISALLOW_IMPLICIT_CONSTRUCTORS(ScopeIterator);
10635 }; 10644 };
10636 10645
10637 10646
10638 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetScopeCount) { 10647 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetScopeCount) {
10639 HandleScope scope(isolate); 10648 HandleScope scope(isolate);
10640 ASSERT(args.length() == 2); 10649 ASSERT(args.length() == 2);
10641 10650
10642 // Check arguments. 10651 // Check arguments.
10643 Object* check; 10652 Object* check;
10644 { MaybeObject* maybe_check = Runtime_CheckExecutionState( 10653 { MaybeObject* maybe_check = Runtime_CheckExecutionState(
10645 RUNTIME_ARGUMENTS(isolate, args)); 10654 RUNTIME_ARGUMENTS(isolate, args));
10646 if (!maybe_check->ToObject(&check)) return maybe_check; 10655 if (!maybe_check->ToObject(&check)) return maybe_check;
10647 } 10656 }
10648 CONVERT_CHECKED(Smi, wrapped_id, args[1]); 10657 CONVERT_CHECKED(Smi, wrapped_id, args[1]);
10649 10658
10650 // Get the frame where the debugging is performed. 10659 // Get the frame where the debugging is performed.
10651 StackFrame::Id id = UnwrapFrameId(wrapped_id); 10660 StackFrame::Id id = UnwrapFrameId(wrapped_id);
10652 JavaScriptFrameIterator it(isolate, id); 10661 JavaScriptFrameIterator it(isolate, id);
10653 JavaScriptFrame* frame = it.frame(); 10662 JavaScriptFrame* frame = it.frame();
10654 10663
10655 // Count the visible scopes. 10664 // Count the visible scopes.
10656 int n = 0; 10665 int n = 0;
10657 for (ScopeIterator it(isolate, frame); !it.Done(); it.Next()) { 10666 for (ScopeIterator it(isolate, frame, 0);
10667 !it.Done();
10668 it.Next()) {
10658 n++; 10669 n++;
10659 } 10670 }
10660 10671
10661 return Smi::FromInt(n); 10672 return Smi::FromInt(n);
10662 } 10673 }
10663 10674
10664 10675
10665 static const int kScopeDetailsTypeIndex = 0; 10676 static const int kScopeDetailsTypeIndex = 0;
10666 static const int kScopeDetailsObjectIndex = 1; 10677 static const int kScopeDetailsObjectIndex = 1;
10667 static const int kScopeDetailsSize = 2; 10678 static const int kScopeDetailsSize = 2;
10668 10679
10669 // Return an array with scope details 10680 // Return an array with scope details
10670 // args[0]: number: break id 10681 // args[0]: number: break id
10671 // args[1]: number: frame index 10682 // args[1]: number: frame index
10672 // args[2]: number: scope index 10683 // args[2]: number: inlined frame index
10684 // args[3]: number: scope index
10673 // 10685 //
10674 // The array returned contains the following information: 10686 // The array returned contains the following information:
10675 // 0: Scope type 10687 // 0: Scope type
10676 // 1: Scope object 10688 // 1: Scope object
10677 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetScopeDetails) { 10689 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetScopeDetails) {
10678 HandleScope scope(isolate); 10690 HandleScope scope(isolate);
10679 ASSERT(args.length() == 3); 10691 ASSERT(args.length() == 4);
10680 10692
10681 // Check arguments. 10693 // Check arguments.
10682 Object* check; 10694 Object* check;
10683 { MaybeObject* maybe_check = Runtime_CheckExecutionState( 10695 { MaybeObject* maybe_check = Runtime_CheckExecutionState(
10684 RUNTIME_ARGUMENTS(isolate, args)); 10696 RUNTIME_ARGUMENTS(isolate, args));
10685 if (!maybe_check->ToObject(&check)) return maybe_check; 10697 if (!maybe_check->ToObject(&check)) return maybe_check;
10686 } 10698 }
10687 CONVERT_CHECKED(Smi, wrapped_id, args[1]); 10699 CONVERT_CHECKED(Smi, wrapped_id, args[1]);
10688 CONVERT_NUMBER_CHECKED(int, index, Int32, args[2]); 10700 CONVERT_NUMBER_CHECKED(int, inlined_frame_index, Int32, args[2]);
10701 CONVERT_NUMBER_CHECKED(int, index, Int32, args[3]);
10689 10702
10690 // Get the frame where the debugging is performed. 10703 // Get the frame where the debugging is performed.
10691 StackFrame::Id id = UnwrapFrameId(wrapped_id); 10704 StackFrame::Id id = UnwrapFrameId(wrapped_id);
10692 JavaScriptFrameIterator frame_it(isolate, id); 10705 JavaScriptFrameIterator frame_it(isolate, id);
10693 JavaScriptFrame* frame = frame_it.frame(); 10706 JavaScriptFrame* frame = frame_it.frame();
10694 10707
10695 // Find the requested scope. 10708 // Find the requested scope.
10696 int n = 0; 10709 int n = 0;
10697 ScopeIterator it(isolate, frame); 10710 ScopeIterator it(isolate, frame, inlined_frame_index);
10698 for (; !it.Done() && n < index; it.Next()) { 10711 for (; !it.Done() && n < index; it.Next()) {
10699 n++; 10712 n++;
10700 } 10713 }
10701 if (it.Done()) { 10714 if (it.Done()) {
10702 return isolate->heap()->undefined_value(); 10715 return isolate->heap()->undefined_value();
10703 } 10716 }
10704 10717
10705 // Calculate the size of the result. 10718 // Calculate the size of the result.
10706 int details_size = kScopeDetailsSize; 10719 int details_size = kScopeDetailsSize;
10707 Handle<FixedArray> details = isolate->factory()->NewFixedArray(details_size); 10720 Handle<FixedArray> details = isolate->factory()->NewFixedArray(details_size);
10708 10721
10709 // Fill in scope details. 10722 // Fill in scope details.
10710 details->set(kScopeDetailsTypeIndex, Smi::FromInt(it.Type())); 10723 details->set(kScopeDetailsTypeIndex, Smi::FromInt(it.Type()));
10711 Handle<JSObject> scope_object = it.ScopeObject(); 10724 Handle<JSObject> scope_object = it.ScopeObject();
10712 RETURN_IF_EMPTY_HANDLE(isolate, scope_object); 10725 RETURN_IF_EMPTY_HANDLE(isolate, scope_object);
10713 details->set(kScopeDetailsObjectIndex, *scope_object); 10726 details->set(kScopeDetailsObjectIndex, *scope_object);
10714 10727
10715 return *isolate->factory()->NewJSArrayWithElements(details); 10728 return *isolate->factory()->NewJSArrayWithElements(details);
10716 } 10729 }
10717 10730
10718 10731
10719 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugPrintScopes) { 10732 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugPrintScopes) {
10720 HandleScope scope(isolate); 10733 HandleScope scope(isolate);
10721 ASSERT(args.length() == 0); 10734 ASSERT(args.length() == 0);
10722 10735
10723 #ifdef DEBUG 10736 #ifdef DEBUG
10724 // Print the scopes for the top frame. 10737 // Print the scopes for the top frame.
10725 StackFrameLocator locator; 10738 StackFrameLocator locator;
10726 JavaScriptFrame* frame = locator.FindJavaScriptFrame(0); 10739 JavaScriptFrame* frame = locator.FindJavaScriptFrame(0);
10727 for (ScopeIterator it(isolate, frame); !it.Done(); it.Next()) { 10740 for (ScopeIterator it(isolate, frame, 0);
10741 !it.Done();
10742 it.Next()) {
10728 it.DebugPrint(); 10743 it.DebugPrint();
10729 } 10744 }
10730 #endif 10745 #endif
10731 return isolate->heap()->undefined_value(); 10746 return isolate->heap()->undefined_value();
10732 } 10747 }
10733 10748
10734 10749
10735 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetThreadCount) { 10750 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetThreadCount) {
10736 HandleScope scope(isolate); 10751 HandleScope scope(isolate);
10737 ASSERT(args.length() == 1); 10752 ASSERT(args.length() == 1);
(...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after
11110 isolate->factory()->NewWithContext(function, new_previous, extension); 11125 isolate->factory()->NewWithContext(function, new_previous, extension);
11111 } 11126 }
11112 return scope.CloseAndEscape(new_current); 11127 return scope.CloseAndEscape(new_current);
11113 } 11128 }
11114 11129
11115 11130
11116 // Helper function to find or create the arguments object for 11131 // Helper function to find or create the arguments object for
11117 // Runtime_DebugEvaluate. 11132 // Runtime_DebugEvaluate.
11118 static Handle<Object> GetArgumentsObject(Isolate* isolate, 11133 static Handle<Object> GetArgumentsObject(Isolate* isolate,
11119 JavaScriptFrame* frame, 11134 JavaScriptFrame* frame,
11135 int inlined_frame_index,
11120 Handle<JSFunction> function, 11136 Handle<JSFunction> function,
11121 Handle<SerializedScopeInfo> scope_info, 11137 Handle<SerializedScopeInfo> scope_info,
11122 const ScopeInfo<>* sinfo, 11138 const ScopeInfo<>* sinfo,
11123 Handle<Context> function_context) { 11139 Handle<Context> function_context) {
11124 // Try to find the value of 'arguments' to pass as parameter. If it is not 11140 // Try to find the value of 'arguments' to pass as parameter. If it is not
11125 // found (that is the debugged function does not reference 'arguments' and 11141 // found (that is the debugged function does not reference 'arguments' and
11126 // does not support eval) then create an 'arguments' object. 11142 // does not support eval) then create an 'arguments' object.
11127 int index; 11143 int index;
11128 if (sinfo->number_of_stack_slots() > 0) { 11144 if (sinfo->number_of_stack_slots() > 0) {
11129 index = scope_info->StackSlotIndex(isolate->heap()->arguments_symbol()); 11145 index = scope_info->StackSlotIndex(isolate->heap()->arguments_symbol());
11130 if (index != -1) { 11146 if (index != -1) {
11147 CHECK(false);
11131 return Handle<Object>(frame->GetExpression(index), isolate); 11148 return Handle<Object>(frame->GetExpression(index), isolate);
11132 } 11149 }
11133 } 11150 }
11134 11151
11135 if (sinfo->number_of_context_slots() > Context::MIN_CONTEXT_SLOTS) { 11152 if (sinfo->number_of_context_slots() > Context::MIN_CONTEXT_SLOTS) {
11136 index = scope_info->ContextSlotIndex(isolate->heap()->arguments_symbol(), 11153 index = scope_info->ContextSlotIndex(isolate->heap()->arguments_symbol(),
11137 NULL); 11154 NULL);
11138 if (index != -1) { 11155 if (index != -1) {
11139 return Handle<Object>(function_context->get(index), isolate); 11156 return Handle<Object>(function_context->get(index), isolate);
11140 } 11157 }
11141 } 11158 }
11142 11159
11143 const int length = frame->ComputeParametersCount(); 11160 ScopedDeoptimizedFrameInfo deoptimized_frame(
11161 frame, inlined_frame_index, isolate);
11162
11163 int length;
11164 if (frame->is_optimized()) {
11165 length = deoptimized_frame.parameters_count();
11166 } else {
11167 length = frame->ComputeParametersCount();
11168 }
11144 Handle<JSObject> arguments = 11169 Handle<JSObject> arguments =
11145 isolate->factory()->NewArgumentsObject(function, length); 11170 isolate->factory()->NewArgumentsObject(function, length);
11146 Handle<FixedArray> array = isolate->factory()->NewFixedArray(length); 11171 Handle<FixedArray> array = isolate->factory()->NewFixedArray(length);
11147 11172
11148 AssertNoAllocation no_gc; 11173 AssertNoAllocation no_gc;
11149 WriteBarrierMode mode = array->GetWriteBarrierMode(no_gc); 11174 WriteBarrierMode mode = array->GetWriteBarrierMode(no_gc);
11150 for (int i = 0; i < length; i++) { 11175 for (int i = 0; i < length; i++) {
11151 array->set(i, frame->GetParameter(i), mode); 11176 if (frame->is_optimized()) {
11177 array->set(i, deoptimized_frame.GetParameter(i), mode);
11178 } else {
11179 array->set(i, frame->GetParameter(i), mode);
11180 }
11152 } 11181 }
11153 arguments->set_elements(*array); 11182 arguments->set_elements(*array);
11154 return arguments; 11183 return arguments;
11155 } 11184 }
11156 11185
11157 11186
11158 static const char kSourceStr[] = 11187 static const char kSourceStr[] =
11159 "(function(arguments,__source__){return eval(__source__);})"; 11188 "(function(arguments,__source__){return eval(__source__);})";
11160 11189
11161 11190
11162 // Evaluate a piece of JavaScript in the context of a stack frame for 11191 // Evaluate a piece of JavaScript in the context of a stack frame for
11163 // debugging. This is accomplished by creating a new context which in its 11192 // debugging. This is accomplished by creating a new context which in its
11164 // extension part has all the parameters and locals of the function on the 11193 // extension part has all the parameters and locals of the function on the
11165 // stack frame. A function which calls eval with the code to evaluate is then 11194 // stack frame. A function which calls eval with the code to evaluate is then
11166 // compiled in this context and called in this context. As this context 11195 // compiled in this context and called in this context. As this context
11167 // replaces the context of the function on the stack frame a new (empty) 11196 // replaces the context of the function on the stack frame a new (empty)
11168 // function is created as well to be used as the closure for the context. 11197 // function is created as well to be used as the closure for the context.
11169 // This function and the context acts as replacements for the function on the 11198 // This function and the context acts as replacements for the function on the
11170 // stack frame presenting the same view of the values of parameters and 11199 // stack frame presenting the same view of the values of parameters and
11171 // local variables as if the piece of JavaScript was evaluated at the point 11200 // local variables as if the piece of JavaScript was evaluated at the point
11172 // where the function on the stack frame is currently stopped. 11201 // where the function on the stack frame is currently stopped.
11173 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) { 11202 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) {
11174 HandleScope scope(isolate); 11203 HandleScope scope(isolate);
11175 11204
11176 // Check the execution state and decode arguments frame and source to be 11205 // Check the execution state and decode arguments frame and source to be
11177 // evaluated. 11206 // evaluated.
11178 ASSERT(args.length() == 5); 11207 ASSERT(args.length() == 6);
11179 Object* check_result; 11208 Object* check_result;
11180 { MaybeObject* maybe_check_result = Runtime_CheckExecutionState( 11209 { MaybeObject* maybe_check_result = Runtime_CheckExecutionState(
11181 RUNTIME_ARGUMENTS(isolate, args)); 11210 RUNTIME_ARGUMENTS(isolate, args));
11182 if (!maybe_check_result->ToObject(&check_result)) { 11211 if (!maybe_check_result->ToObject(&check_result)) {
11183 return maybe_check_result; 11212 return maybe_check_result;
11184 } 11213 }
11185 } 11214 }
11186 CONVERT_CHECKED(Smi, wrapped_id, args[1]); 11215 CONVERT_CHECKED(Smi, wrapped_id, args[1]);
11187 CONVERT_ARG_CHECKED(String, source, 2); 11216 CONVERT_NUMBER_CHECKED(int, inlined_frame_index, Int32, args[2]);
11188 CONVERT_BOOLEAN_CHECKED(disable_break, args[3]); 11217 CONVERT_ARG_CHECKED(String, source, 3);
11189 Handle<Object> additional_context(args[4]); 11218 CONVERT_BOOLEAN_CHECKED(disable_break, args[4]);
11219 Handle<Object> additional_context(args[5]);
11190 11220
11191 // Handle the processing of break. 11221 // Handle the processing of break.
11192 DisableBreak disable_break_save(disable_break); 11222 DisableBreak disable_break_save(disable_break);
11193 11223
11194 // Get the frame where the debugging is performed. 11224 // Get the frame where the debugging is performed.
11195 StackFrame::Id id = UnwrapFrameId(wrapped_id); 11225 StackFrame::Id id = UnwrapFrameId(wrapped_id);
11196 JavaScriptFrameIterator it(isolate, id); 11226 JavaScriptFrameIterator it(isolate, id);
11197 JavaScriptFrame* frame = it.frame(); 11227 JavaScriptFrame* frame = it.frame();
11198 Handle<JSFunction> function(JSFunction::cast(frame->function())); 11228 Handle<JSFunction> function(JSFunction::cast(frame->function()));
11199 Handle<SerializedScopeInfo> scope_info(function->shared()->scope_info()); 11229 Handle<SerializedScopeInfo> scope_info(function->shared()->scope_info());
(...skipping 19 matching lines...) Expand all
11219 isolate->factory()->NewFunction(isolate->factory()->empty_string(), 11249 isolate->factory()->NewFunction(isolate->factory()->empty_string(),
11220 isolate->factory()->undefined_value()); 11250 isolate->factory()->undefined_value());
11221 go_between->set_context(function->context()); 11251 go_between->set_context(function->context());
11222 #ifdef DEBUG 11252 #ifdef DEBUG
11223 ScopeInfo<> go_between_sinfo(go_between->shared()->scope_info()); 11253 ScopeInfo<> go_between_sinfo(go_between->shared()->scope_info());
11224 ASSERT(go_between_sinfo.number_of_parameters() == 0); 11254 ASSERT(go_between_sinfo.number_of_parameters() == 0);
11225 ASSERT(go_between_sinfo.number_of_context_slots() == 0); 11255 ASSERT(go_between_sinfo.number_of_context_slots() == 0);
11226 #endif 11256 #endif
11227 11257
11228 // Materialize the content of the local scope into a JSObject. 11258 // Materialize the content of the local scope into a JSObject.
11229 Handle<JSObject> local_scope = MaterializeLocalScope(isolate, frame); 11259 Handle<JSObject> local_scope = MaterializeLocalScope(
11260 isolate, frame, inlined_frame_index);
11230 RETURN_IF_EMPTY_HANDLE(isolate, local_scope); 11261 RETURN_IF_EMPTY_HANDLE(isolate, local_scope);
11231 11262
11232 // Allocate a new context for the debug evaluation and set the extension 11263 // Allocate a new context for the debug evaluation and set the extension
11233 // object build. 11264 // object build.
11234 Handle<Context> context = 11265 Handle<Context> context =
11235 isolate->factory()->NewFunctionContext(Context::MIN_CONTEXT_SLOTS, 11266 isolate->factory()->NewFunctionContext(Context::MIN_CONTEXT_SLOTS,
11236 go_between); 11267 go_between);
11237 context->set_extension(*local_scope); 11268 context->set_extension(*local_scope);
11238 // Copy any with contexts present and chain them in front of this context. 11269 // Copy any with contexts present and chain them in front of this context.
11239 Handle<Context> frame_context(Context::cast(frame->context())); 11270 Handle<Context> frame_context(Context::cast(frame->context()));
(...skipping 28 matching lines...) Expand all
11268 isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, context); 11299 isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, context);
11269 11300
11270 // Invoke the result of the compilation to get the evaluation function. 11301 // Invoke the result of the compilation to get the evaluation function.
11271 bool has_pending_exception; 11302 bool has_pending_exception;
11272 Handle<Object> receiver(frame->receiver(), isolate); 11303 Handle<Object> receiver(frame->receiver(), isolate);
11273 Handle<Object> evaluation_function = 11304 Handle<Object> evaluation_function =
11274 Execution::Call(compiled_function, receiver, 0, NULL, 11305 Execution::Call(compiled_function, receiver, 0, NULL,
11275 &has_pending_exception); 11306 &has_pending_exception);
11276 if (has_pending_exception) return Failure::Exception(); 11307 if (has_pending_exception) return Failure::Exception();
11277 11308
11278 Handle<Object> arguments = GetArgumentsObject(isolate, frame, 11309 Handle<Object> arguments = GetArgumentsObject(isolate,
11310 frame, inlined_frame_index,
11279 function, scope_info, 11311 function, scope_info,
11280 &sinfo, function_context); 11312 &sinfo, function_context);
11281 11313
11282 // Invoke the evaluation function and return the result. 11314 // Invoke the evaluation function and return the result.
11283 const int argc = 2; 11315 const int argc = 2;
11284 Object** argv[argc] = { arguments.location(), 11316 Object** argv[argc] = { arguments.location(),
11285 Handle<Object>::cast(source).location() }; 11317 Handle<Object>::cast(source).location() };
11286 Handle<Object> result = 11318 Handle<Object> result =
11287 Execution::Call(Handle<JSFunction>::cast(evaluation_function), receiver, 11319 Execution::Call(Handle<JSFunction>::cast(evaluation_function), receiver,
11288 argc, argv, &has_pending_exception); 11320 argc, argv, &has_pending_exception);
(...skipping 1323 matching lines...) Expand 10 before | Expand all | Expand 10 after
12612 } else { 12644 } else {
12613 // Handle last resort GC and make sure to allow future allocations 12645 // Handle last resort GC and make sure to allow future allocations
12614 // to grow the heap without causing GCs (if possible). 12646 // to grow the heap without causing GCs (if possible).
12615 isolate->counters()->gc_last_resort_from_js()->Increment(); 12647 isolate->counters()->gc_last_resort_from_js()->Increment();
12616 isolate->heap()->CollectAllGarbage(false); 12648 isolate->heap()->CollectAllGarbage(false);
12617 } 12649 }
12618 } 12650 }
12619 12651
12620 12652
12621 } } // namespace v8::internal 12653 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698