| OLD | NEW | 
|      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 9920 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   9931     if (!maybe_result->ToObject(&result)) return maybe_result; |   9931     if (!maybe_result->ToObject(&result)) return maybe_result; | 
|   9932   } |   9932   } | 
|   9933  |   9933  | 
|   9934   // Count all frames which are relevant to debugging stack trace. |   9934   // Count all frames which are relevant to debugging stack trace. | 
|   9935   int n = 0; |   9935   int n = 0; | 
|   9936   StackFrame::Id id = isolate->debug()->break_frame_id(); |   9936   StackFrame::Id id = isolate->debug()->break_frame_id(); | 
|   9937   if (id == StackFrame::NO_ID) { |   9937   if (id == StackFrame::NO_ID) { | 
|   9938     // If there is no JavaScript stack frame count is 0. |   9938     // If there is no JavaScript stack frame count is 0. | 
|   9939     return Smi::FromInt(0); |   9939     return Smi::FromInt(0); | 
|   9940   } |   9940   } | 
|   9941   for (JavaScriptFrameIterator it(isolate, id); !it.done(); it.Advance()) n++; |   9941  | 
 |   9942   for (JavaScriptFrameIterator it(isolate, id); !it.done(); it.Advance()) { | 
 |   9943     n += it.frame()->GetInlineCount(); | 
 |   9944   } | 
|   9942   return Smi::FromInt(n); |   9945   return Smi::FromInt(n); | 
|   9943 } |   9946 } | 
|   9944  |   9947  | 
|   9945  |   9948  | 
|   9946 static const int kFrameDetailsFrameIdIndex = 0; |   9949 static const int kFrameDetailsFrameIdIndex = 0; | 
|   9947 static const int kFrameDetailsReceiverIndex = 1; |   9950 static const int kFrameDetailsReceiverIndex = 1; | 
|   9948 static const int kFrameDetailsFunctionIndex = 2; |   9951 static const int kFrameDetailsFunctionIndex = 2; | 
|   9949 static const int kFrameDetailsArgumentCountIndex = 3; |   9952 static const int kFrameDetailsArgumentCountIndex = 3; | 
|   9950 static const int kFrameDetailsLocalCountIndex = 4; |   9953 static const int kFrameDetailsLocalCountIndex = 4; | 
|   9951 static const int kFrameDetailsSourcePositionIndex = 5; |   9954 static const int kFrameDetailsSourcePositionIndex = 5; | 
|   9952 static const int kFrameDetailsConstructCallIndex = 6; |   9955 static const int kFrameDetailsConstructCallIndex = 6; | 
|   9953 static const int kFrameDetailsAtReturnIndex = 7; |   9956 static const int kFrameDetailsAtReturnIndex = 7; | 
|   9954 static const int kFrameDetailsDebuggerFrameIndex = 8; |   9957 static const int kFrameDetailsFlagsIndex = 8; | 
|   9955 static const int kFrameDetailsFirstDynamicIndex = 9; |   9958 static const int kFrameDetailsFirstDynamicIndex = 9; | 
|   9956  |   9959  | 
|   9957 // Return an array with frame details |   9960 // Return an array with frame details | 
|   9958 // args[0]: number: break id |   9961 // args[0]: number: break id | 
|   9959 // args[1]: number: frame index |   9962 // args[1]: number: frame index | 
|   9960 // |   9963 // | 
|   9961 // The array returned contains the following information: |   9964 // The array returned contains the following information: | 
|   9962 // 0: Frame id |   9965 // 0: Frame id | 
|   9963 // 1: Receiver |   9966 // 1: Receiver | 
|   9964 // 2: Function |   9967 // 2: Function | 
|   9965 // 3: Argument count |   9968 // 3: Argument count | 
|   9966 // 4: Local count |   9969 // 4: Local count | 
|   9967 // 5: Source position |   9970 // 5: Source position | 
|   9968 // 6: Constructor call |   9971 // 6: Constructor call | 
|   9969 // 7: Is at return |   9972 // 7: Is at return | 
|   9970 // 8: Debugger frame |   9973 // 8: Flags | 
|   9971 // Arguments name, value |   9974 // Arguments name, value | 
|   9972 // Locals name, value |   9975 // Locals name, value | 
|   9973 // Return value if any |   9976 // Return value if any | 
|   9974 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameDetails) { |   9977 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameDetails) { | 
|   9975   HandleScope scope(isolate); |   9978   HandleScope scope(isolate); | 
|   9976   ASSERT(args.length() == 2); |   9979   ASSERT(args.length() == 2); | 
|   9977  |   9980  | 
|   9978   // Check arguments. |   9981   // Check arguments. | 
|   9979   Object* check; |   9982   Object* check; | 
|   9980   { MaybeObject* maybe_check = Runtime_CheckExecutionState( |   9983   { MaybeObject* maybe_check = Runtime_CheckExecutionState( | 
|   9981       RUNTIME_ARGUMENTS(isolate, args)); |   9984       RUNTIME_ARGUMENTS(isolate, args)); | 
|   9982     if (!maybe_check->ToObject(&check)) return maybe_check; |   9985     if (!maybe_check->ToObject(&check)) return maybe_check; | 
|   9983   } |   9986   } | 
|   9984   CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]); |   9987   CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]); | 
|   9985   Heap* heap = isolate->heap(); |   9988   Heap* heap = isolate->heap(); | 
|   9986  |   9989  | 
|   9987   // Find the relevant frame with the requested index. |   9990   // Find the relevant frame with the requested index. | 
|   9988   StackFrame::Id id = isolate->debug()->break_frame_id(); |   9991   StackFrame::Id id = isolate->debug()->break_frame_id(); | 
|   9989   if (id == StackFrame::NO_ID) { |   9992   if (id == StackFrame::NO_ID) { | 
|   9990     // If there are no JavaScript stack frames return undefined. |   9993     // If there are no JavaScript stack frames return undefined. | 
|   9991     return heap->undefined_value(); |   9994     return heap->undefined_value(); | 
|   9992   } |   9995   } | 
 |   9996  | 
 |   9997   int deoptimized_frame_index = -1;  // Frame index in optimized frame. | 
 |   9998   DeoptimizedFrameInfo* deoptimized_frame = NULL; | 
 |   9999  | 
|   9993   int count = 0; |  10000   int count = 0; | 
|   9994   JavaScriptFrameIterator it(isolate, id); |  10001   JavaScriptFrameIterator it(isolate, id); | 
|   9995   for (; !it.done(); it.Advance()) { |  10002   for (; !it.done(); it.Advance()) { | 
|   9996     if (count == index) break; |  10003     if (index < count + it.frame()->GetInlineCount()) break; | 
|   9997     count++; |  10004     count += it.frame()->GetInlineCount(); | 
|   9998   } |  10005   } | 
|   9999   if (it.done()) return heap->undefined_value(); |  10006   if (it.done()) return heap->undefined_value(); | 
|  10000  |  10007  | 
|  10001   bool is_optimized_frame = |  10008   if (it.frame()->is_optimized()) { | 
|  10002       it.frame()->LookupCode()->kind() == Code::OPTIMIZED_FUNCTION; |  10009     deoptimized_frame_index = | 
 |  10010         it.frame()->GetInlineCount() - (index - count) - 1; | 
 |  10011     deoptimized_frame = Deoptimizer::DebuggerInspectableFrame( | 
 |  10012         it.frame(), | 
 |  10013         deoptimized_frame_index, | 
 |  10014         isolate); | 
 |  10015   } | 
|  10003  |  10016  | 
|  10004   // Traverse the saved contexts chain to find the active context for the |  10017   // Traverse the saved contexts chain to find the active context for the | 
|  10005   // selected frame. |  10018   // selected frame. | 
|  10006   SaveContext* save = isolate->save_context(); |  10019   SaveContext* save = isolate->save_context(); | 
|  10007   while (save != NULL && !save->below(it.frame())) { |  10020   while (save != NULL && !save->below(it.frame())) { | 
|  10008     save = save->prev(); |  10021     save = save->prev(); | 
|  10009   } |  10022   } | 
|  10010   ASSERT(save != NULL); |  10023   ASSERT(save != NULL); | 
|  10011  |  10024  | 
|  10012   // Get the frame id. |  10025   // Get the frame id. | 
|  10013   Handle<Object> frame_id(WrapFrameId(it.frame()->id()), isolate); |  10026   Handle<Object> frame_id(WrapFrameId(it.frame()->id()), isolate); | 
|  10014  |  10027  | 
|  10015   // Find source position. |  10028   // Find source position. | 
|  10016   int position = |  10029   int position = | 
|  10017       it.frame()->LookupCode()->SourcePosition(it.frame()->pc()); |  10030       it.frame()->LookupCode()->SourcePosition(it.frame()->pc()); | 
|  10018  |  10031  | 
|  10019   // Check for constructor frame. |  10032   // Check for constructor frame. | 
|  10020   bool constructor = it.frame()->IsConstructor(); |  10033   bool constructor = it.frame()->IsConstructor(); | 
|  10021  |  10034  | 
|  10022   // Get scope info and read from it for local variable information. |  10035   // Get scope info and read from it for local variable information. | 
|  10023   Handle<JSFunction> function(JSFunction::cast(it.frame()->function())); |  10036   Handle<JSFunction> function(JSFunction::cast(it.frame()->function())); | 
|  10024   Handle<SerializedScopeInfo> scope_info(function->shared()->scope_info()); |  10037   Handle<SerializedScopeInfo> scope_info(function->shared()->scope_info()); | 
 |  10038   ASSERT(*scope_info != SerializedScopeInfo::Empty()); | 
|  10025   ScopeInfo<> info(*scope_info); |  10039   ScopeInfo<> info(*scope_info); | 
|  10026  |  10040  | 
|  10027   // Get the locals names and values into a temporary array. |  10041   // Get the locals names and values into a temporary array. | 
|  10028   // |  10042   // | 
|  10029   // TODO(1240907): Hide compiler-introduced stack variables |  10043   // TODO(1240907): Hide compiler-introduced stack variables | 
|  10030   // (e.g. .result)?  For users of the debugger, they will probably be |  10044   // (e.g. .result)?  For users of the debugger, they will probably be | 
|  10031   // confusing. |  10045   // confusing. | 
|  10032   Handle<FixedArray> locals = |  10046   Handle<FixedArray> locals = | 
|  10033       isolate->factory()->NewFixedArray(info.NumberOfLocals() * 2); |  10047       isolate->factory()->NewFixedArray(info.NumberOfLocals() * 2); | 
|  10034  |  10048  | 
|  10035   // Fill in the values of the locals. |  10049   // Fill in the values of the locals. | 
|  10036   if (is_optimized_frame) { |  10050   int i = 0; | 
|  10037     // If we are inspecting an optimized frame use undefined as the |  10051   for (; i < info.number_of_stack_slots(); ++i) { | 
|  10038     // value for all locals. |  10052     // Use the value from the stack. | 
|  10039     // |  10053     locals->set(i * 2, *info.LocalName(i)); | 
|  10040     // TODO(1140): We should be able to get the correct values |  10054     if (it.frame()->is_optimized()) { | 
|  10041     // for locals in optimized frames. |  10055       // Get the value from the deoptimized frame. | 
|  10042     for (int i = 0; i < info.NumberOfLocals(); i++) { |  10056       locals->set(i * 2 + 1, | 
|  10043       locals->set(i * 2, *info.LocalName(i)); |  10057                   deoptimized_frame->GetExpression(i)); | 
|  10044       locals->set(i * 2 + 1, isolate->heap()->undefined_value()); |  10058     } else { | 
|  10045     } |  10059       // Get the value from the stack. | 
|  10046   } else { |  | 
|  10047     int i = 0; |  | 
|  10048     for (; i < info.number_of_stack_slots(); ++i) { |  | 
|  10049       // Use the value from the stack. |  | 
|  10050       locals->set(i * 2, *info.LocalName(i)); |  | 
|  10051       locals->set(i * 2 + 1, it.frame()->GetExpression(i)); |  10060       locals->set(i * 2 + 1, it.frame()->GetExpression(i)); | 
|  10052     } |  10061     } | 
|  10053     // Get the context containing declarations. |  10062   } | 
|  10054     Handle<Context> context( |  10063   // Get the context containing declarations. | 
|  10055         Context::cast(it.frame()->context())->declaration_context()); |  10064   Handle<Context> context( | 
|  10056     for (; i < info.NumberOfLocals(); ++i) { |  10065       Context::cast(it.frame()->context())->declaration_context()); | 
|  10057       Handle<String> name = info.LocalName(i); |  10066   for (; i < info.NumberOfLocals(); ++i) { | 
|  10058       locals->set(i * 2, *name); |  10067     Handle<String> name = info.LocalName(i); | 
|  10059       locals->set(i * 2 + 1, |  10068     locals->set(i * 2, *name); | 
|  10060                   context->get(scope_info->ContextSlotIndex(*name, NULL))); |  10069     locals->set(i * 2 + 1, | 
|  10061     } |  10070                 context->get(scope_info->ContextSlotIndex(*name, NULL))); | 
|  10062   } |  10071   } | 
|  10063  |  10072  | 
|  10064   // Check whether this frame is positioned at return. If not top |  10073   // Check whether this frame is positioned at return. If not top | 
|  10065   // frame or if the frame is optimized it cannot be at a return. |  10074   // frame or if the frame is optimized it cannot be at a return. | 
|  10066   bool at_return = false; |  10075   bool at_return = false; | 
|  10067   if (!is_optimized_frame && index == 0) { |  10076   if (!it.frame()->is_optimized() && index == 0) { | 
|  10068     at_return = isolate->debug()->IsBreakAtReturn(it.frame()); |  10077     at_return = isolate->debug()->IsBreakAtReturn(it.frame()); | 
|  10069   } |  10078   } | 
|  10070  |  10079  | 
|  10071   // If positioned just before return find the value to be returned and add it |  10080   // If positioned just before return find the value to be returned and add it | 
|  10072   // to the frame information. |  10081   // to the frame information. | 
|  10073   Handle<Object> return_value = isolate->factory()->undefined_value(); |  10082   Handle<Object> return_value = isolate->factory()->undefined_value(); | 
|  10074   if (at_return) { |  10083   if (at_return) { | 
|  10075     StackFrameIterator it2(isolate); |  10084     StackFrameIterator it2(isolate); | 
|  10076     Address internal_frame_sp = NULL; |  10085     Address internal_frame_sp = NULL; | 
|  10077     while (!it2.done()) { |  10086     while (!it2.done()) { | 
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  10138   } else { |  10147   } else { | 
|  10139     details->set(kFrameDetailsSourcePositionIndex, heap->undefined_value()); |  10148     details->set(kFrameDetailsSourcePositionIndex, heap->undefined_value()); | 
|  10140   } |  10149   } | 
|  10141  |  10150  | 
|  10142   // Add the constructor information. |  10151   // Add the constructor information. | 
|  10143   details->set(kFrameDetailsConstructCallIndex, heap->ToBoolean(constructor)); |  10152   details->set(kFrameDetailsConstructCallIndex, heap->ToBoolean(constructor)); | 
|  10144  |  10153  | 
|  10145   // Add the at return information. |  10154   // Add the at return information. | 
|  10146   details->set(kFrameDetailsAtReturnIndex, heap->ToBoolean(at_return)); |  10155   details->set(kFrameDetailsAtReturnIndex, heap->ToBoolean(at_return)); | 
|  10147  |  10156  | 
|  10148   // Add information on whether this frame is invoked in the debugger context. |  10157   // Add flags to indicate information on whether this frame is | 
|  10149   details->set(kFrameDetailsDebuggerFrameIndex, |  10158   //   bit 0: invoked in the debugger context. | 
|  10150                heap->ToBoolean(*save->context() == |  10159   //   bit 1: optimized frame. | 
|  10151                    *isolate->debug()->debug_context())); |  10160   //   bit 2: inlined in optimized frame | 
 |  10161   int flags = 0; | 
 |  10162   if (*save->context() == *isolate->debug()->debug_context()) { | 
 |  10163     flags |= 1 << 0; | 
 |  10164   } | 
 |  10165   if (it.frame()->is_optimized()) { | 
 |  10166     flags |= 1 << 1; | 
 |  10167     if (deoptimized_frame_index > 0) { | 
 |  10168       flags |= 1 << 2; | 
 |  10169     } | 
 |  10170   } | 
 |  10171   details->set(kFrameDetailsFlagsIndex, Smi::FromInt(flags)); | 
|  10152  |  10172  | 
|  10153   // Fill the dynamic part. |  10173   // Fill the dynamic part. | 
|  10154   int details_index = kFrameDetailsFirstDynamicIndex; |  10174   int details_index = kFrameDetailsFirstDynamicIndex; | 
|  10155  |  10175  | 
|  10156   // Add arguments name and value. |  10176   // Add arguments name and value. | 
|  10157   for (int i = 0; i < argument_count; i++) { |  10177   for (int i = 0; i < argument_count; i++) { | 
|  10158     // Name of the argument. |  10178     // Name of the argument. | 
|  10159     if (i < info.number_of_parameters()) { |  10179     if (i < info.number_of_parameters()) { | 
|  10160       details->set(details_index++, *info.parameter_name(i)); |  10180       details->set(details_index++, *info.parameter_name(i)); | 
|  10161     } else { |  10181     } else { | 
|  10162       details->set(details_index++, heap->undefined_value()); |  10182       details->set(details_index++, heap->undefined_value()); | 
|  10163     } |  10183     } | 
|  10164  |  10184  | 
|  10165     // Parameter value. If we are inspecting an optimized frame, use |  10185     // Parameter value. If we are inspecting an optimized frame, use | 
|  10166     // undefined as the value. |  10186     // undefined as the value. | 
|  10167     // |  10187     // | 
|  10168     // TODO(3141533): We should be able to get the actual parameter |  10188     // TODO(3141533): We should be able to get the actual parameter | 
|  10169     // value for optimized frames. |  10189     // value for optimized frames. | 
|  10170     if (!is_optimized_frame && |  10190     if (!it.frame()->is_optimized() && | 
|  10171         (i < it.frame()->ComputeParametersCount())) { |  10191         (i < it.frame()->ComputeParametersCount())) { | 
|  10172       details->set(details_index++, it.frame()->GetParameter(i)); |  10192       details->set(details_index++, it.frame()->GetParameter(i)); | 
|  10173     } else { |  10193     } else { | 
|  10174       details->set(details_index++, heap->undefined_value()); |  10194       details->set(details_index++, heap->undefined_value()); | 
|  10175     } |  10195     } | 
|  10176   } |  10196   } | 
|  10177  |  10197  | 
|  10178   // Add locals name and value from the temporary copy from the function frame. |  10198   // Add locals name and value from the temporary copy from the function frame. | 
|  10179   for (int i = 0; i < info.NumberOfLocals() * 2; i++) { |  10199   for (int i = 0; i < info.NumberOfLocals() * 2; i++) { | 
|  10180     details->set(details_index++, locals->get(i)); |  10200     details->set(details_index++, locals->get(i)); | 
| (...skipping 15 matching lines...) Expand all  Loading... | 
|  10196     // by creating correct wrapper object based on the calling frame's |  10216     // by creating correct wrapper object based on the calling frame's | 
|  10197     // global context. |  10217     // global context. | 
|  10198     it.Advance(); |  10218     it.Advance(); | 
|  10199     Handle<Context> calling_frames_global_context( |  10219     Handle<Context> calling_frames_global_context( | 
|  10200         Context::cast(Context::cast(it.frame()->context())->global_context())); |  10220         Context::cast(Context::cast(it.frame()->context())->global_context())); | 
|  10201     receiver = |  10221     receiver = | 
|  10202         isolate->factory()->ToObject(receiver, calling_frames_global_context); |  10222         isolate->factory()->ToObject(receiver, calling_frames_global_context); | 
|  10203   } |  10223   } | 
|  10204   details->set(kFrameDetailsReceiverIndex, *receiver); |  10224   details->set(kFrameDetailsReceiverIndex, *receiver); | 
|  10205  |  10225  | 
 |  10226   // Get rid of the calculated deoptimized frame if any. | 
 |  10227   if (deoptimized_frame != NULL) { | 
 |  10228     Deoptimizer::DeleteDebuggerInspectableFrame(deoptimized_frame, | 
 |  10229                                                 isolate); | 
 |  10230   } | 
 |  10231  | 
|  10206   ASSERT_EQ(details_size, details_index); |  10232   ASSERT_EQ(details_size, details_index); | 
|  10207   return *isolate->factory()->NewJSArrayWithElements(details); |  10233   return *isolate->factory()->NewJSArrayWithElements(details); | 
|  10208 } |  10234 } | 
|  10209  |  10235  | 
|  10210  |  10236  | 
|  10211 // Copy all the context locals into an object used to materialize a scope. |  10237 // Copy all the context locals into an object used to materialize a scope. | 
|  10212 static bool CopyContextLocalsToScopeObject( |  10238 static bool CopyContextLocalsToScopeObject( | 
|  10213     Isolate* isolate, |  10239     Isolate* isolate, | 
|  10214     Handle<SerializedScopeInfo> serialized_scope_info, |  10240     Handle<SerializedScopeInfo> serialized_scope_info, | 
|  10215     ScopeInfo<>& scope_info, |  10241     ScopeInfo<>& scope_info, | 
| (...skipping 2308 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  12524   } else { |  12550   } else { | 
|  12525     // Handle last resort GC and make sure to allow future allocations |  12551     // Handle last resort GC and make sure to allow future allocations | 
|  12526     // to grow the heap without causing GCs (if possible). |  12552     // to grow the heap without causing GCs (if possible). | 
|  12527     isolate->counters()->gc_last_resort_from_js()->Increment(); |  12553     isolate->counters()->gc_last_resort_from_js()->Increment(); | 
|  12528     isolate->heap()->CollectAllGarbage(false); |  12554     isolate->heap()->CollectAllGarbage(false); | 
|  12529   } |  12555   } | 
|  12530 } |  12556 } | 
|  12531  |  12557  | 
|  12532  |  12558  | 
|  12533 } }  // namespace v8::internal |  12559 } }  // namespace v8::internal | 
| OLD | NEW |