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

Side by Side Diff: src/runtime.cc

Issue 123021: Add scope chain information to the debugger (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 6 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
« no previous file with comments | « src/runtime.h ('k') | test/mjsunit/debug-scopes.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. 1 // Copyright 2006-2009 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 6088 matching lines...) Expand 10 before | Expand all | Expand 10 after
6099 Context::cast(Context::cast(it.frame()->context())->global_context())); 6099 Context::cast(Context::cast(it.frame()->context())->global_context()));
6100 receiver = Factory::ToObject(receiver, calling_frames_global_context); 6100 receiver = Factory::ToObject(receiver, calling_frames_global_context);
6101 } 6101 }
6102 details->set(kFrameDetailsReceiverIndex, *receiver); 6102 details->set(kFrameDetailsReceiverIndex, *receiver);
6103 6103
6104 ASSERT_EQ(details_size, details_index); 6104 ASSERT_EQ(details_size, details_index);
6105 return *Factory::NewJSArrayWithElements(details); 6105 return *Factory::NewJSArrayWithElements(details);
6106 } 6106 }
6107 6107
6108 6108
6109 // Copy all the context locals into an object used to materialize a scope.
6110 static void CopyContextLocalsToScopeObject(Handle<Code> code,
6111 ScopeInfo<>& scope_info,
6112 Handle<Context> context,
6113 Handle<JSObject> scope_object) {
6114 // Fill all context locals to the context extension.
6115 for (int i = Context::MIN_CONTEXT_SLOTS;
6116 i < scope_info.number_of_context_slots();
6117 i++) {
6118 int context_index =
6119 ScopeInfo<>::ContextSlotIndex(*code,
6120 *scope_info.context_slot_name(i),
6121 NULL);
6122
6123 // Don't include the arguments shadow (.arguments) context variable.
6124 if (*scope_info.context_slot_name(i) != Heap::arguments_shadow_symbol()) {
6125 SetProperty(scope_object,
6126 scope_info.context_slot_name(i),
6127 Handle<Object>(context->get(context_index)), NONE);
6128 }
6129 }
6130 }
6131
6132
6133 // Create a plain JSObject which materializes the local scope for the specified
6134 // frame.
6135 static Handle<JSObject> MaterializeLocalScope(JavaScriptFrame* frame) {
6136 Handle<JSFunction> function(JSFunction::cast(frame->function()));
6137 Handle<Code> code(function->code());
6138 ScopeInfo<> scope_info(*code);
6139
6140 // Allocate and initialize a JSObject with all the arguments, stack locals
6141 // heap locals and extension properties of the debugged function.
6142 Handle<JSObject> local_scope = Factory::NewJSObject(Top::object_function());
6143
6144 // First fill all parameters.
6145 for (int i = 0; i < scope_info.number_of_parameters(); ++i) {
6146 SetProperty(local_scope,
6147 scope_info.parameter_name(i),
6148 Handle<Object>(frame->GetParameter(i)), NONE);
6149 }
6150
6151 // Second fill all stack locals.
6152 for (int i = 0; i < scope_info.number_of_stack_slots(); i++) {
6153 SetProperty(local_scope,
6154 scope_info.stack_slot_name(i),
6155 Handle<Object>(frame->GetExpression(i)), NONE);
6156 }
6157
6158 // Third fill all context locals.
6159 Handle<Context> frame_context(Context::cast(frame->context()));
6160 Handle<Context> function_context(frame_context->fcontext());
6161 CopyContextLocalsToScopeObject(code, scope_info,
6162 function_context, local_scope);
6163
6164 // Finally copy any properties from the function context extension. This will
6165 // be variables introduced by eval.
6166 if (function_context->closure() == *function) {
6167 if (function_context->has_extension() &&
6168 !function_context->IsGlobalContext()) {
6169 Handle<JSObject> ext(JSObject::cast(function_context->extension()));
6170 Handle<FixedArray> keys = GetKeysInFixedArrayFor(ext);
6171 for (int i = 0; i < keys->length(); i++) {
6172 // Names of variables introduced by eval are strings.
6173 ASSERT(keys->get(i)->IsString());
6174 Handle<String> key(String::cast(keys->get(i)));
6175 SetProperty(local_scope, key, GetProperty(ext, key), NONE);
6176 }
6177 }
6178 }
6179 return local_scope;
6180 }
6181
6182
6183 // Create a plain JSObject which materializes the closure content for the
6184 // context.
6185 static Handle<JSObject> MaterializeClosure(Handle<Context> context) {
6186 ASSERT(context->is_function_context());
6187
6188 Handle<Code> code(context->closure()->code());
6189 ScopeInfo<> scope_info(*code);
6190
6191 // Allocate and initialize a JSObject with all the content of theis function
6192 // closure.
6193 Handle<JSObject> closure_scope = Factory::NewJSObject(Top::object_function());
6194
6195 // Check whether the arguments shadow object exists.
6196 int arguments_shadow_index =
6197 ScopeInfo<>::ContextSlotIndex(*code,
6198 Heap::arguments_shadow_symbol(),
6199 NULL);
6200 if (arguments_shadow_index >= 0) {
6201 // In this case all the arguments are available in the arguments shadow
6202 // object.
6203 Handle<JSObject> arguments_shadow(
6204 JSObject::cast(context->get(arguments_shadow_index)));
6205 for (int i = 0; i < scope_info.number_of_parameters(); ++i) {
6206 SetProperty(closure_scope,
6207 scope_info.parameter_name(i),
6208 Handle<Object>(arguments_shadow->GetElement(i)), NONE);
6209 }
6210 }
6211
6212 // Fill all context locals to the context extension.
6213 CopyContextLocalsToScopeObject(code, scope_info, context, closure_scope);
6214
6215 // Finally copy any properties from the function context extension. This will
6216 // be variables introduced by eval.
6217 if (context->has_extension()) {
6218 Handle<JSObject> ext(JSObject::cast(context->extension()));
6219 Handle<FixedArray> keys = GetKeysInFixedArrayFor(ext);
6220 for (int i = 0; i < keys->length(); i++) {
6221 // Names of variables introduced by eval are strings.
6222 ASSERT(keys->get(i)->IsString());
6223 Handle<String> key(String::cast(keys->get(i)));
6224 SetProperty(closure_scope, key, GetProperty(ext, key), NONE);
6225 }
6226 }
6227
6228 return closure_scope;
6229 }
6230
6231
6232 // Iterate over the actual scopes visible from a stack frame. All scopes are
6233 // backed by an actual context except the local scope, which is inserted
6234 // "artifically" in the context chain.
6235 class ScopeIterator {
6236 public:
6237 enum ScopeType {
6238 ScopeTypeGlobal = 0,
6239 ScopeTypeLocal,
6240 ScopeTypeWith,
6241 ScopeTypeClosure
6242 };
6243
6244 explicit ScopeIterator(JavaScriptFrame* frame)
6245 : frame_(frame),
6246 function_(JSFunction::cast(frame->function())),
6247 context_(Context::cast(frame->context())),
6248 local_done_(false),
6249 at_local_(false) {
6250
6251 // Check whether the first scope is actually a local scope.
6252 if (context_->IsGlobalContext()) {
6253 // If there is a stack slot for .result then this local scope has been
6254 // created for evaluating top level code and it is not a real local scope.
6255 // Checking for the existence of .result seems fragile, but the scope info
6256 // saved with the code object does not otherwise have that information.
6257 Handle<Code> code(function_->code());
6258 int index = ScopeInfo<>::StackSlotIndex(*code, Heap::result_symbol());
6259 at_local_ = index < 0;
6260 } else if (context_->is_function_context()) {
6261 at_local_ = true;
6262 }
6263 }
6264
6265 // More scopes?
6266 bool Done() { return context_.is_null(); }
6267
6268 // Move to the next scope.
6269 void Next() {
6270 // If at a local scope mark the local scope as passed.
6271 if (at_local_) {
6272 at_local_ = false;
6273 local_done_ = true;
6274
6275 // If the current context is not associated with the local scope the
6276 // current context is the next real scope, so don't move to the next
6277 // context in this case.
6278 if (context_->closure() != *function_) {
6279 return;
6280 }
6281 }
6282
6283 // The global scope is always the last in the chain.
6284 if (context_->IsGlobalContext()) {
6285 context_ = Handle<Context>();
6286 return;
6287 }
6288
6289 // Move to the next context.
6290 if (context_->is_function_context()) {
6291 context_ = Handle<Context>(Context::cast(context_->closure()->context()));
6292 } else {
6293 context_ = Handle<Context>(context_->previous());
6294 }
6295
6296 // If passing the local scope indicate that the current scope is now the
6297 // local scope.
6298 if (!local_done_ &&
6299 (context_->IsGlobalContext() || (context_->is_function_context()))) {
6300 at_local_ = true;
6301 }
6302 }
6303
6304 // Return the type of the current scope.
6305 int Type() {
6306 if (at_local_) {
6307 return ScopeTypeLocal;
6308 }
6309 if (context_->IsGlobalContext()) {
6310 ASSERT(context_->global()->IsGlobalObject());
6311 return ScopeTypeGlobal;
6312 }
6313 if (context_->is_function_context()) {
6314 return ScopeTypeClosure;
6315 }
6316 ASSERT(context_->has_extension());
6317 ASSERT(!context_->extension()->IsJSContextExtensionObject());
6318 return ScopeTypeWith;
6319 }
6320
6321 // Return the JavaScript object with the content of the current scope.
6322 Handle<JSObject> ScopeObject() {
6323 switch (Type()) {
6324 case ScopeIterator::ScopeTypeGlobal:
6325 return Handle<JSObject>(CurrentContext()->global());
6326 break;
6327 case ScopeIterator::ScopeTypeLocal:
6328 // Materialize the content of the local scope into a JSObject.
6329 return MaterializeLocalScope(frame_);
6330 break;
6331 case ScopeIterator::ScopeTypeWith:
6332 // Return the with object.
6333 return Handle<JSObject>(CurrentContext()->extension());
6334 break;
6335 case ScopeIterator::ScopeTypeClosure:
6336 // Materialize the content of the closure scope into a JSObject.
6337 return MaterializeClosure(CurrentContext());
6338 break;
6339 default:
6340 UNREACHABLE();
6341 return Handle<JSObject>();
6342 }
6343 }
6344
6345 // Return the context for this scope. For the local context there might not
6346 // be an actual context.
6347 Handle<Context> CurrentContext() {
6348 if (at_local_ && context_->closure() != *function_) {
6349 return Handle<Context>();
6350 }
6351 return context_;
6352 }
6353
6354 #ifdef DEBUG
6355 // Debug print of the content of the current scope.
6356 void DebugPrint() {
6357 switch (Type()) {
6358 case ScopeIterator::ScopeTypeGlobal:
6359 PrintF("Global:\n");
6360 CurrentContext()->Print();
6361 break;
6362
6363 case ScopeIterator::ScopeTypeLocal: {
6364 PrintF("Local:\n");
6365 Handle<Code> code(function_->code());
6366 ScopeInfo<> scope_info(*code);
6367 scope_info.Print();
6368 if (!CurrentContext().is_null()) {
6369 CurrentContext()->Print();
6370 if (CurrentContext()->has_extension()) {
6371 Handle<JSObject> extension =
6372 Handle<JSObject>(CurrentContext()->extension());
6373 if (extension->IsJSContextExtensionObject()) {
6374 extension->Print();
6375 }
6376 }
6377 }
6378 break;
6379 }
6380
6381 case ScopeIterator::ScopeTypeWith: {
6382 PrintF("With:\n");
6383 Handle<JSObject> extension =
6384 Handle<JSObject>(CurrentContext()->extension());
6385 extension->Print();
6386 break;
6387 }
6388
6389 case ScopeIterator::ScopeTypeClosure: {
6390 PrintF("Closure:\n");
6391 CurrentContext()->Print();
6392 if (CurrentContext()->has_extension()) {
6393 Handle<JSObject> extension =
6394 Handle<JSObject>(CurrentContext()->extension());
6395 if (extension->IsJSContextExtensionObject()) {
6396 extension->Print();
6397 }
6398 }
6399 break;
6400 }
6401
6402 default:
6403 UNREACHABLE();
6404 }
6405 PrintF("\n");
6406 }
6407 #endif
6408
6409 private:
6410 JavaScriptFrame* frame_;
6411 Handle<JSFunction> function_;
6412 Handle<Context> context_;
6413 bool local_done_;
6414 bool at_local_;
6415
6416 DISALLOW_IMPLICIT_CONSTRUCTORS(ScopeIterator);
6417 };
6418
6419
6420 static Object* Runtime_GetScopeCount(Arguments args) {
6421 HandleScope scope;
6422 ASSERT(args.length() == 2);
6423
6424 // Check arguments.
6425 Object* check = Runtime_CheckExecutionState(args);
6426 if (check->IsFailure()) return check;
6427 CONVERT_CHECKED(Smi, wrapped_id, args[1]);
6428
6429 // Get the frame where the debugging is performed.
6430 StackFrame::Id id = UnwrapFrameId(wrapped_id);
6431 JavaScriptFrameIterator it(id);
6432 JavaScriptFrame* frame = it.frame();
6433
6434 // Count the visible scopes.
6435 int n = 0;
6436 for (ScopeIterator it(frame); !it.Done(); it.Next()) {
6437 n++;
6438 }
6439
6440 return Smi::FromInt(n);
6441 }
6442
6443
6444 static const int kScopeDetailsTypeIndex = 0;
6445 static const int kScopeDetailsObjectIndex = 1;
6446 static const int kScopeDetailsSize = 2;
6447
6448 // Return an array with scope details
6449 // args[0]: number: break id
6450 // args[1]: number: frame index
6451 // args[2]: number: scope index
6452 //
6453 // The array returned contains the following information:
6454 // 0: Scope type
6455 // 1: Scope object
6456 static Object* Runtime_GetScopeDetails(Arguments args) {
6457 HandleScope scope;
6458 ASSERT(args.length() == 3);
6459
6460 // Check arguments.
6461 Object* check = Runtime_CheckExecutionState(args);
6462 if (check->IsFailure()) return check;
6463 CONVERT_CHECKED(Smi, wrapped_id, args[1]);
6464 CONVERT_NUMBER_CHECKED(int, index, Int32, args[2]);
6465
6466 // Get the frame where the debugging is performed.
6467 StackFrame::Id id = UnwrapFrameId(wrapped_id);
6468 JavaScriptFrameIterator frame_it(id);
6469 JavaScriptFrame* frame = frame_it.frame();
6470
6471 // Find the requested scope.
6472 int n = 0;
6473 ScopeIterator it(frame);
6474 for (; !it.Done() && n < index; it.Next()) {
6475 n++;
6476 }
6477 if (it.Done()) {
6478 return Heap::undefined_value();
6479 }
6480
6481 // Calculate the size of the result.
6482 int details_size = kScopeDetailsSize;
6483 Handle<FixedArray> details = Factory::NewFixedArray(details_size);
6484
6485 // Fill in scope details.
6486 details->set(kScopeDetailsTypeIndex, Smi::FromInt(it.Type()));
6487 details->set(kScopeDetailsObjectIndex, *it.ScopeObject());
6488
6489 return *Factory::NewJSArrayWithElements(details);
6490 }
6491
6492
6493 static Object* Runtime_DebugPrintScopes(Arguments args) {
6494 HandleScope scope;
6495 ASSERT(args.length() == 0);
6496
6497 #ifdef DEBUG
6498 // Print the scopes for the top frame.
6499 StackFrameLocator locator;
6500 JavaScriptFrame* frame = locator.FindJavaScriptFrame(0);
6501 for (ScopeIterator it(frame); !it.Done(); it.Next()) {
6502 it.DebugPrint();
6503 }
6504 #endif
6505 return Heap::undefined_value();
6506 }
6507
6508
6109 static Object* Runtime_GetCFrames(Arguments args) { 6509 static Object* Runtime_GetCFrames(Arguments args) {
6110 HandleScope scope; 6510 HandleScope scope;
6111 ASSERT(args.length() == 1); 6511 ASSERT(args.length() == 1);
6112 Object* result = Runtime_CheckExecutionState(args); 6512 Object* result = Runtime_CheckExecutionState(args);
6113 if (result->IsFailure()) return result; 6513 if (result->IsFailure()) return result;
6114 6514
6115 #if V8_HOST_ARCH_64_BIT 6515 #if V8_HOST_ARCH_64_BIT
6116 UNIMPLEMENTED(); 6516 UNIMPLEMENTED();
6117 return Heap::undefined_value(); 6517 return Heap::undefined_value();
6118 #else 6518 #else
(...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after
6561 // are looked at before the extension object. 6961 // are looked at before the extension object.
6562 Handle<JSFunction> go_between = 6962 Handle<JSFunction> go_between =
6563 Factory::NewFunction(Factory::empty_string(), Factory::undefined_value()); 6963 Factory::NewFunction(Factory::empty_string(), Factory::undefined_value());
6564 go_between->set_context(function->context()); 6964 go_between->set_context(function->context());
6565 #ifdef DEBUG 6965 #ifdef DEBUG
6566 ScopeInfo<> go_between_sinfo(go_between->shared()->code()); 6966 ScopeInfo<> go_between_sinfo(go_between->shared()->code());
6567 ASSERT(go_between_sinfo.number_of_parameters() == 0); 6967 ASSERT(go_between_sinfo.number_of_parameters() == 0);
6568 ASSERT(go_between_sinfo.number_of_context_slots() == 0); 6968 ASSERT(go_between_sinfo.number_of_context_slots() == 0);
6569 #endif 6969 #endif
6570 6970
6571 // Allocate and initialize a context extension object with all the 6971 // Materialize the content of the local scope into a JSObject.
6572 // arguments, stack locals heap locals and extension properties of the 6972 Handle<JSObject> local_scope = MaterializeLocalScope(frame);
6573 // debugged function.
6574 Handle<JSObject> context_ext = Factory::NewJSObject(Top::object_function());
6575 // First fill all parameters to the context extension.
6576 for (int i = 0; i < sinfo.number_of_parameters(); ++i) {
6577 SetProperty(context_ext,
6578 sinfo.parameter_name(i),
6579 Handle<Object>(frame->GetParameter(i)), NONE);
6580 }
6581 // Second fill all stack locals to the context extension.
6582 for (int i = 0; i < sinfo.number_of_stack_slots(); i++) {
6583 SetProperty(context_ext,
6584 sinfo.stack_slot_name(i),
6585 Handle<Object>(frame->GetExpression(i)), NONE);
6586 }
6587 // Third fill all context locals to the context extension.
6588 Handle<Context> frame_context(Context::cast(frame->context()));
6589 Handle<Context> function_context(frame_context->fcontext());
6590 for (int i = Context::MIN_CONTEXT_SLOTS;
6591 i < sinfo.number_of_context_slots();
6592 ++i) {
6593 int context_index =
6594 ScopeInfo<>::ContextSlotIndex(*code, *sinfo.context_slot_name(i), NULL);
6595 SetProperty(context_ext,
6596 sinfo.context_slot_name(i),
6597 Handle<Object>(function_context->get(context_index)), NONE);
6598 }
6599 // Finally copy any properties from the function context extension. This will
6600 // be variables introduced by eval.
6601 if (function_context->has_extension() &&
6602 !function_context->IsGlobalContext()) {
6603 Handle<JSObject> ext(JSObject::cast(function_context->extension()));
6604 Handle<FixedArray> keys = GetKeysInFixedArrayFor(ext);
6605 for (int i = 0; i < keys->length(); i++) {
6606 // Names of variables introduced by eval are strings.
6607 ASSERT(keys->get(i)->IsString());
6608 Handle<String> key(String::cast(keys->get(i)));
6609 SetProperty(context_ext, key, GetProperty(ext, key), NONE);
6610 }
6611 }
6612 6973
6613 // Allocate a new context for the debug evaluation and set the extension 6974 // Allocate a new context for the debug evaluation and set the extension
6614 // object build. 6975 // object build.
6615 Handle<Context> context = 6976 Handle<Context> context =
6616 Factory::NewFunctionContext(Context::MIN_CONTEXT_SLOTS, go_between); 6977 Factory::NewFunctionContext(Context::MIN_CONTEXT_SLOTS, go_between);
6617 context->set_extension(*context_ext); 6978 context->set_extension(*local_scope);
6618 // Copy any with contexts present and chain them in front of this context. 6979 // Copy any with contexts present and chain them in front of this context.
6980 Handle<Context> frame_context(Context::cast(frame->context()));
6981 Handle<Context> function_context(frame_context->fcontext());
6619 context = CopyWithContextChain(frame_context, context); 6982 context = CopyWithContextChain(frame_context, context);
6620 6983
6621 // Wrap the evaluation statement in a new function compiled in the newly 6984 // Wrap the evaluation statement in a new function compiled in the newly
6622 // created context. The function has one parameter which has to be called 6985 // created context. The function has one parameter which has to be called
6623 // 'arguments'. This it to have access to what would have been 'arguments' in 6986 // 'arguments'. This it to have access to what would have been 'arguments' in
6624 // the function being debugged. 6987 // the function being debugged.
6625 // function(arguments,__source__) {return eval(__source__);} 6988 // function(arguments,__source__) {return eval(__source__);}
6626 static const char* source_str = 6989 static const char* source_str =
6627 "function(arguments,__source__){return eval(__source__);}"; 6990 "function(arguments,__source__){return eval(__source__);}";
6628 static const int source_str_length = strlen(source_str); 6991 static const int source_str_length = strlen(source_str);
(...skipping 21 matching lines...) Expand all
6650 function_context); 7013 function_context);
6651 7014
6652 // Invoke the evaluation function and return the result. 7015 // Invoke the evaluation function and return the result.
6653 const int argc = 2; 7016 const int argc = 2;
6654 Object** argv[argc] = { arguments.location(), 7017 Object** argv[argc] = { arguments.location(),
6655 Handle<Object>::cast(source).location() }; 7018 Handle<Object>::cast(source).location() };
6656 Handle<Object> result = 7019 Handle<Object> result =
6657 Execution::Call(Handle<JSFunction>::cast(evaluation_function), receiver, 7020 Execution::Call(Handle<JSFunction>::cast(evaluation_function), receiver,
6658 argc, argv, &has_pending_exception); 7021 argc, argv, &has_pending_exception);
6659 if (has_pending_exception) return Failure::Exception(); 7022 if (has_pending_exception) return Failure::Exception();
7023
7024 // Skip the global proxy as it has no properties and always delegates to the
7025 // real global object.
7026 if (result->IsJSGlobalProxy()) {
7027 result = Handle<JSObject>(JSObject::cast(result->GetPrototype()));
7028 }
7029
6660 return *result; 7030 return *result;
6661 } 7031 }
6662 7032
6663 7033
6664 static Object* Runtime_DebugEvaluateGlobal(Arguments args) { 7034 static Object* Runtime_DebugEvaluateGlobal(Arguments args) {
6665 HandleScope scope; 7035 HandleScope scope;
6666 7036
6667 // Check the execution state and decode arguments frame and source to be 7037 // Check the execution state and decode arguments frame and source to be
6668 // evaluated. 7038 // evaluated.
6669 ASSERT(args.length() == 3); 7039 ASSERT(args.length() == 3);
(...skipping 434 matching lines...) Expand 10 before | Expand all | Expand 10 after
7104 } else { 7474 } else {
7105 // Handle last resort GC and make sure to allow future allocations 7475 // Handle last resort GC and make sure to allow future allocations
7106 // to grow the heap without causing GCs (if possible). 7476 // to grow the heap without causing GCs (if possible).
7107 Counters::gc_last_resort_from_js.Increment(); 7477 Counters::gc_last_resort_from_js.Increment();
7108 Heap::CollectAllGarbage(); 7478 Heap::CollectAllGarbage();
7109 } 7479 }
7110 } 7480 }
7111 7481
7112 7482
7113 } } // namespace v8::internal 7483 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/runtime.h ('k') | test/mjsunit/debug-scopes.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698