51 #include "../include/v8-debug.h"
56 #ifdef ENABLE_DEBUGGER_SUPPORT
59 Debug::Debug(Isolate* isolate)
60 : has_break_points_(
false),
62 debug_info_list_(
NULL),
63 disable_break_(
false),
64 break_on_exception_(
false),
65 break_on_uncaught_exception_(
false),
66 debug_break_return_(
NULL),
67 debug_break_slot_(
NULL),
79 ScopedVector<char> data(s->
Length() + 1);
80 if (data.start() ==
NULL) {
85 PrintF(
"%s\n", data.start());
89 static Handle<Code> ComputeCallDebugPrepareStepIn(
int argc,
Code::Kind kind) {
90 Isolate* isolate = Isolate::Current();
91 return isolate->stub_cache()->ComputeCallDebugPrepareStepIn(argc, kind);
96 Handle<Context> context = isolate->debug()->debugger_entry()->GetContext();
100 Handle<Context> global_context(context->global_context());
105 BreakLocationIterator::BreakLocationIterator(Handle<DebugInfo> debug_info,
106 BreakLocatorType
type) {
107 debug_info_ = debug_info;
109 reloc_iterator_ =
NULL;
110 reloc_iterator_original_ =
NULL;
115 BreakLocationIterator::~BreakLocationIterator() {
118 delete reloc_iterator_;
119 delete reloc_iterator_original_;
123 void BreakLocationIterator::Next() {
124 AssertNoAllocation nogc;
129 bool first = break_point_ == -1;
130 while (!RinfoDone()) {
131 if (!first) RinfoNext();
133 if (RinfoDone())
return;
137 if (RelocInfo::IsPosition(rmode())) {
138 if (RelocInfo::IsStatementPosition(rmode())) {
139 statement_position_ =
static_cast<int>(
140 rinfo()->data() - debug_info_->shared()->start_position());
144 position_ =
static_cast<int>(
145 rinfo()->data() - debug_info_->shared()->start_position());
147 ASSERT(statement_position_ >= 0);
150 if (IsDebugBreakSlot()) {
154 }
else if (RelocInfo::IsCodeTarget(rmode())) {
158 Address target = original_rinfo()->target_address();
160 if ((code->is_inline_cache_stub() &&
161 !code->is_binary_op_stub() &&
162 !code->is_unary_op_stub() &&
163 !code->is_compare_ic_stub() &&
164 !code->is_to_boolean_ic_stub()) ||
165 RelocInfo::IsConstructCall(rmode())) {
170 if (IsDebuggerStatement()) {
174 if (
type_ == ALL_BREAK_LOCATIONS) {
175 if (Debug::IsBreakStub(code)) {
181 if (Debug::IsSourceBreakStub(code)) {
190 if (RelocInfo::IsJSReturn(rmode())) {
192 if (debug_info_->shared()->HasSourceCode()) {
193 position_ = debug_info_->shared()->end_position() -
194 debug_info_->shared()->start_position() - 1;
198 statement_position_ = position_;
206 void BreakLocationIterator::Next(
int count) {
215 void BreakLocationIterator::FindBreakLocationFromAddress(
Address pc) {
217 int closest_break_point = 0;
221 if (this->
pc() < pc && pc - this->
pc() < distance) {
222 closest_break_point = break_point();
223 distance =
static_cast<int>(pc - this->
pc());
225 if (distance == 0)
break;
232 Next(closest_break_point);
237 void BreakLocationIterator::FindBreakLocationFromPosition(
int position) {
240 int closest_break_point = 0;
244 if (position <= statement_position() &&
245 statement_position() - position < distance) {
246 closest_break_point = break_point();
247 distance = statement_position() - position;
249 if (distance == 0)
break;
256 Next(closest_break_point);
262 if (reloc_iterator_ !=
NULL)
delete reloc_iterator_;
263 if (reloc_iterator_original_ !=
NULL)
delete reloc_iterator_original_;
264 reloc_iterator_ =
new RelocIterator(debug_info_->code());
265 reloc_iterator_original_ =
new RelocIterator(debug_info_->original_code());
270 statement_position_ = 1;
275 bool BreakLocationIterator::Done()
const {
280 void BreakLocationIterator::SetBreakPoint(Handle<Object> break_point_object) {
283 if (!HasBreakPoint()) {
286 ASSERT(IsDebugBreak() || IsDebuggerStatement());
288 DebugInfo::SetBreakPoint(debug_info_, code_position(),
289 position(), statement_position(),
294 void BreakLocationIterator::ClearBreakPoint(Handle<Object> break_point_object) {
296 DebugInfo::ClearBreakPoint(debug_info_, code_position(), break_point_object);
298 if (!HasBreakPoint()) {
305 void BreakLocationIterator::SetOneShot() {
307 if (IsDebuggerStatement()) {
312 if (HasBreakPoint()) {
322 void BreakLocationIterator::ClearOneShot() {
324 if (IsDebuggerStatement()) {
329 if (HasBreakPoint()) {
340 void BreakLocationIterator::SetDebugBreak() {
342 if (IsDebuggerStatement()) {
350 if (IsDebugBreak()) {
354 if (RelocInfo::IsJSReturn(rmode())) {
356 SetDebugBreakAtReturn();
357 }
else if (IsDebugBreakSlot()) {
359 SetDebugBreakAtSlot();
368 void BreakLocationIterator::ClearDebugBreak() {
370 if (IsDebuggerStatement()) {
374 if (RelocInfo::IsJSReturn(rmode())) {
376 ClearDebugBreakAtReturn();
377 }
else if (IsDebugBreakSlot()) {
379 ClearDebugBreakAtSlot();
382 ClearDebugBreakAtIC();
388 void BreakLocationIterator::PrepareStepIn() {
393 Address target = rinfo()->target_address();
395 if (target_code->is_call_stub() || target_code->is_keyed_call_stub()) {
401 Handle<Code> stub = ComputeCallDebugPrepareStepIn(
402 target_code->arguments_count(), target_code->kind());
403 if (IsDebugBreak()) {
404 original_rinfo()->set_target_address(stub->entry());
406 rinfo()->set_target_address(stub->entry());
412 Handle<Code> maybe_call_function_stub = target_code;
413 if (IsDebugBreak()) {
414 Address original_target = original_rinfo()->target_address();
415 maybe_call_function_stub =
418 bool is_call_function_stub =
419 (maybe_call_function_stub->kind() ==
Code::STUB &&
420 maybe_call_function_stub->major_key() == CodeStub::CallFunction);
429 ASSERT(RelocInfo::IsConstructCall(rmode()) ||
430 target_code->is_inline_cache_stub() ||
431 is_call_function_stub);
438 bool BreakLocationIterator::IsExit()
const {
439 return (RelocInfo::IsJSReturn(rmode()));
443 bool BreakLocationIterator::HasBreakPoint() {
444 return debug_info_->HasBreakPoint(code_position());
449 bool BreakLocationIterator::IsDebugBreak() {
450 if (RelocInfo::IsJSReturn(rmode())) {
451 return IsDebugBreakAtReturn();
452 }
else if (IsDebugBreakSlot()) {
453 return IsDebugBreakAtSlot();
455 return Debug::IsDebugBreak(rinfo()->target_address());
460 void BreakLocationIterator::SetDebugBreakAtIC() {
463 original_rinfo()->set_target_address(rinfo()->target_address());
465 RelocInfo::Mode mode = rmode();
466 if (RelocInfo::IsCodeTarget(mode)) {
467 Address target = rinfo()->target_address();
472 Handle<Code> dbgbrk_code(Debug::FindDebugBreak(target_code, mode));
473 rinfo()->set_target_address(dbgbrk_code->entry());
478 void BreakLocationIterator::ClearDebugBreakAtIC() {
480 rinfo()->set_target_address(original_rinfo()->target_address());
484 bool BreakLocationIterator::IsDebuggerStatement() {
489 bool BreakLocationIterator::IsDebugBreakSlot() {
490 return RelocInfo::DEBUG_BREAK_SLOT == rmode();
494 Object* BreakLocationIterator::BreakPointObjects() {
495 return debug_info_->GetBreakPointObjects(code_position());
502 void BreakLocationIterator::ClearAllDebugBreak() {
510 bool BreakLocationIterator::RinfoDone()
const {
511 ASSERT(reloc_iterator_->done() == reloc_iterator_original_->done());
512 return reloc_iterator_->done();
516 void BreakLocationIterator::RinfoNext() {
517 reloc_iterator_->next();
518 reloc_iterator_original_->next();
520 ASSERT(reloc_iterator_->done() == reloc_iterator_original_->done());
521 if (!reloc_iterator_->done()) {
522 ASSERT(rmode() == original_rmode());
529 void Debug::ThreadInit() {
530 thread_local_.break_count_ = 0;
531 thread_local_.break_id_ = 0;
532 thread_local_.break_frame_id_ = StackFrame::NO_ID;
533 thread_local_.last_step_action_ = StepNone;
534 thread_local_.last_statement_position_ = RelocInfo::kNoPosition;
535 thread_local_.step_count_ = 0;
536 thread_local_.last_fp_ = 0;
537 thread_local_.queued_step_count_ = 0;
538 thread_local_.step_into_fp_ = 0;
539 thread_local_.step_out_fp_ = 0;
540 thread_local_.after_break_target_ = 0;
542 thread_local_.debugger_entry_ =
NULL;
543 thread_local_.pending_interrupts_ = 0;
544 thread_local_.restarter_frame_function_pointer_ =
NULL;
548 char* Debug::ArchiveDebug(
char* storage) {
550 memcpy(to, reinterpret_cast<char*>(&thread_local_),
sizeof(ThreadLocal));
551 to +=
sizeof(ThreadLocal);
552 memcpy(to, reinterpret_cast<char*>(®isters_),
sizeof(registers_));
554 ASSERT(to <= storage + ArchiveSpacePerThread());
555 return storage + ArchiveSpacePerThread();
559 char* Debug::RestoreDebug(
char* storage) {
560 char* from = storage;
561 memcpy(reinterpret_cast<char*>(&thread_local_), from,
sizeof(ThreadLocal));
562 from +=
sizeof(ThreadLocal);
563 memcpy(reinterpret_cast<char*>(®isters_), from,
sizeof(registers_));
564 ASSERT(from <= storage + ArchiveSpacePerThread());
565 return storage + ArchiveSpacePerThread();
569 int Debug::ArchiveSpacePerThread() {
581 ASSERT(bottom_js_frame->is_java_script());
597 const int Debug::kFrameDropperFrameSize = 4;
600 void ScriptCache::Add(Handle<Script> script) {
601 GlobalHandles* global_handles = Isolate::Current()->global_handles();
603 int id =
Smi::cast(script->id())->value();
604 HashMap::Entry* entry =
606 if (entry->value !=
NULL) {
607 ASSERT(*script == *reinterpret_cast<Script**>(entry->value));
613 Handle<Script> script_ =
615 (global_handles->Create(*script)));
616 global_handles->MakeWeak(
617 reinterpret_cast<Object**>(script_.location()),
619 ScriptCache::HandleWeakScript);
620 entry->value = script_.location();
624 Handle<FixedArray> ScriptCache::GetScripts() {
625 Handle<FixedArray> instances =
FACTORY->NewFixedArray(occupancy());
627 for (HashMap::Entry* entry = Start(); entry !=
NULL; entry = Next(entry)) {
629 if (entry->value !=
NULL) {
630 instances->set(count, *reinterpret_cast<Script**>(entry->value));
638 void ScriptCache::ProcessCollectedScripts() {
639 Debugger* debugger = Isolate::Current()->debugger();
640 for (
int i = 0; i < collected_scripts_.length(); i++) {
641 debugger->OnScriptCollected(collected_scripts_[i]);
643 collected_scripts_.Clear();
647 void ScriptCache::Clear() {
648 GlobalHandles* global_handles = Isolate::Current()->global_handles();
650 for (HashMap::Entry* entry = Start(); entry !=
NULL; entry = Next(entry)) {
652 Object** location =
reinterpret_cast<Object**
>(entry->value);
653 ASSERT((*location)->IsScript());
654 global_handles->ClearWeakness(location);
655 global_handles->Destroy(location);
663 ScriptCache* script_cache =
reinterpret_cast<ScriptCache*
>(data);
667 ASSERT((*location)->IsScript());
670 int id =
Smi::cast((*location)->id())->value();
671 script_cache->Remove(reinterpret_cast<void*>(
id), Hash(
id));
672 script_cache->collected_scripts_.Add(
id);
680 void Debug::SetUp(
bool create_heap_objects) {
682 if (create_heap_objects) {
684 debug_break_return_ =
685 isolate_->builtins()->builtin(Builtins::kReturn_DebugBreak);
686 ASSERT(debug_break_return_->IsCode());
689 isolate_->builtins()->builtin(Builtins::kSlot_DebugBreak);
690 ASSERT(debug_break_slot_->IsCode());
696 Debug* debug = Isolate::Current()->debug();
697 DebugInfoListNode* node =
reinterpret_cast<DebugInfoListNode*
>(data);
702 BreakLocationIterator it(node->debug_info(), ALL_BREAK_LOCATIONS);
703 it.ClearAllDebugBreak();
704 debug->RemoveDebugInfo(node->debug_info());
706 node = debug->debug_info_list_;
707 while (node !=
NULL) {
708 ASSERT(node != reinterpret_cast<DebugInfoListNode*>(data));
715 DebugInfoListNode::DebugInfoListNode(DebugInfo* debug_info): next_(
NULL) {
716 GlobalHandles* global_handles = Isolate::Current()->global_handles();
719 (global_handles->Create(debug_info)));
720 global_handles->MakeWeak(
721 reinterpret_cast<Object**>(debug_info_.location()),
723 Debug::HandleWeakDebugInfo);
727 DebugInfoListNode::~DebugInfoListNode() {
728 Isolate::Current()->global_handles()->Destroy(
729 reinterpret_cast<Object**>(debug_info_.location()));
733 bool Debug::CompileDebuggerScript(
int index) {
734 Isolate* isolate = Isolate::Current();
735 Factory* factory = isolate->factory();
736 HandleScope scope(isolate);
744 Handle<String> source_code =
745 isolate->bootstrapper()->NativesSourceLookup(index);
747 Handle<String> script_name = factory->NewStringFromAscii(name);
750 Handle<SharedFunctionInfo> function_info;
758 if (function_info.is_null()) {
759 ASSERT(isolate->has_pending_exception());
760 isolate->clear_pending_exception();
765 Handle<Context> context = isolate->global_context();
766 bool caught_exception;
767 Handle<JSFunction>
function =
768 factory->NewFunctionFromSharedFunctionInfo(function_info, context);
770 Handle<Object> exception =
772 0,
NULL, &caught_exception);
775 if (caught_exception) {
776 ASSERT(!isolate->has_pending_exception());
777 MessageLocation computed_location;
778 isolate->ComputeLocation(&computed_location);
780 "error_loading_debugger", &computed_location,
781 Vector<Handle<Object> >::empty(), Handle<String>(), Handle<JSArray>());
782 ASSERT(!isolate->has_pending_exception());
783 isolate->set_pending_exception(*exception);
785 isolate->clear_pending_exception();
790 Handle<Script> script(
Script::cast(function->shared()->script()));
798 if (IsLoaded())
return true;
800 Debugger* debugger = isolate_->debugger();
804 if (debugger->compiling_natives() ||
805 debugger->is_loading_debugger())
807 debugger->set_loading_debugger(
true);
811 DisableBreak disable(
true);
812 PostponeInterruptsScope postpone(isolate_);
815 HandleScope scope(isolate_);
816 Handle<Context> context =
817 isolate_->bootstrapper()->CreateEnvironment(
824 if (context.is_null())
return false;
827 SaveContext save(isolate_);
828 isolate_->set_context(*context);
831 Handle<String> key = isolate_->factory()->LookupAsciiSymbol(
"builtins");
832 Handle<GlobalObject> global = Handle<GlobalObject>(context->global());
840 debugger->set_compiling_natives(
true);
841 bool caught_exception =
845 if (FLAG_enable_liveedit) {
846 caught_exception = caught_exception ||
850 debugger->set_compiling_natives(
false);
854 debugger->set_loading_debugger(
false);
857 if (caught_exception)
return false;
860 debug_context_ = context;
866 void Debug::Unload() {
873 DestroyScriptCache();
876 Isolate::Current()->global_handles()->Destroy(
877 reinterpret_cast<Object**>(debug_context_.location()));
878 debug_context_ = Handle<Context>();
883 void Debug::PreemptionWhileInDebugger() {
885 Debug::set_interrupts_pending(
PREEMPT);
889 void Debug::Iterate(ObjectVisitor* v) {
890 v->VisitPointer(BitCast<Object**>(&(debug_break_return_)));
891 v->VisitPointer(BitCast<Object**>(&(debug_break_slot_)));
895 void Debug::PutValuesOnStackAndDie(
int start,
906 Heap* heap = isolate_->heap();
907 HandleScope scope(isolate_);
908 ASSERT(args.length() == 0);
910 thread_local_.frame_drop_mode_ = FRAMES_UNTOUCHED;
914 JavaScriptFrame* frame = it.frame();
917 if (disable_break() || !
Load()) {
918 SetAfterBreakTarget(frame);
919 return heap->undefined_value();
923 EnterDebugger debugger;
924 if (debugger.FailedToEnter()) {
925 return heap->undefined_value();
929 PostponeInterruptsScope postpone(isolate_);
932 Handle<SharedFunctionInfo> shared =
934 Handle<DebugInfo> debug_info = GetDebugInfo(shared);
937 BreakLocationIterator break_location_iterator(debug_info,
938 ALL_BREAK_LOCATIONS);
939 break_location_iterator.FindBreakLocationFromAddress(frame->pc());
942 if (!StepNextContinue(&break_location_iterator, frame)) {
944 if (thread_local_.step_count_ > 0) {
945 thread_local_.step_count_--;
951 Handle<Object> break_points_hit(heap->undefined_value());
952 if (break_location_iterator.HasBreakPoint()) {
953 Handle<Object> break_point_objects =
954 Handle<Object>(break_location_iterator.BreakPointObjects());
955 break_points_hit = CheckBreakPoints(break_point_objects);
960 if (StepOutActive() && frame->fp() != step_out_fp() &&
961 break_points_hit->IsUndefined() ) {
963 ASSERT(thread_local_.step_count_ == 0);
964 }
else if (!break_points_hit->IsUndefined() ||
965 (thread_local_.last_step_action_ != StepNone &&
966 thread_local_.step_count_ == 0)) {
973 if (thread_local_.queued_step_count_ > 0) {
975 int step_count = thread_local_.queued_step_count_;
978 thread_local_.queued_step_count_ = 0;
980 PrepareStep(StepNext, step_count);
983 isolate_->debugger()->OnDebugBreak(break_points_hit,
false);
985 }
else if (thread_local_.last_step_action_ != StepNone) {
988 StepAction step_action = thread_local_.last_step_action_;
989 int step_count = thread_local_.step_count_;
993 if (step_action == StepNext && frame->fp() < thread_local_.last_fp_) {
997 while (!it.done() && it.frame()->fp() < thread_local_.last_fp_) {
1009 PutValuesOnStackAndDie(0xBEEEEEEE,
1011 thread_local_.last_fp_,
1015 }
else if (it.frame()->fp() != thread_local_.last_fp_) {
1017 PutValuesOnStackAndDie(0xBEEEEEEE,
1019 thread_local_.last_fp_,
1026 if (it.frame()->fp() == thread_local_.last_fp_) {
1027 if (step_count > 1) {
1030 thread_local_.queued_step_count_ = step_count - 1;
1034 step_action = StepOut;
1043 PrepareStep(step_action, step_count);
1046 if (thread_local_.frame_drop_mode_ == FRAMES_UNTOUCHED) {
1047 SetAfterBreakTarget(frame);
1048 }
else if (thread_local_.frame_drop_mode_ ==
1049 FRAME_DROPPED_IN_IC_CALL) {
1051 Code* plain_return = isolate_->builtins()->builtin(
1052 Builtins::kPlainReturn_LiveEdit);
1053 thread_local_.after_break_target_ = plain_return->entry();
1054 }
else if (thread_local_.frame_drop_mode_ ==
1055 FRAME_DROPPED_IN_DEBUG_SLOT_CALL) {
1058 Code* plain_return = isolate_->builtins()->builtin(
1059 Builtins::kFrameDropper_LiveEdit);
1060 thread_local_.after_break_target_ = plain_return->entry();
1061 }
else if (thread_local_.frame_drop_mode_ ==
1062 FRAME_DROPPED_IN_DIRECT_CALL) {
1064 }
else if (thread_local_.frame_drop_mode_ ==
1065 FRAME_DROPPED_IN_RETURN_CALL) {
1066 Code* plain_return = isolate_->builtins()->builtin(
1067 Builtins::kFrameDropper_LiveEdit);
1068 thread_local_.after_break_target_ = plain_return->entry();
1073 return heap->undefined_value();
1078 return isolate->debug()->Break(args);
1085 Handle<Object> Debug::CheckBreakPoints(Handle<Object> break_point_objects) {
1086 Factory* factory = isolate_->factory();
1090 Handle<FixedArray> break_points_hit;
1091 int break_points_hit_count = 0;
1092 ASSERT(!break_point_objects->IsUndefined());
1093 if (break_point_objects->IsFixedArray()) {
1095 break_points_hit = factory->NewFixedArray(array->length());
1096 for (
int i = 0; i < array->length(); i++) {
1097 Handle<Object> o(array->get(i));
1098 if (CheckBreakPoint(o)) {
1099 break_points_hit->set(break_points_hit_count++, *o);
1103 break_points_hit = factory->NewFixedArray(1);
1104 if (CheckBreakPoint(break_point_objects)) {
1105 break_points_hit->set(break_points_hit_count++, *break_point_objects);
1110 if (break_points_hit_count == 0) {
1111 return factory->undefined_value();
1114 Handle<JSArray> result = factory->NewJSArrayWithElements(break_points_hit);
1115 result->set_length(
Smi::FromInt(break_points_hit_count));
1121 bool Debug::CheckBreakPoint(Handle<Object> break_point_object) {
1122 Factory* factory = isolate_->factory();
1123 HandleScope scope(isolate_);
1126 if (!break_point_object->IsJSObject())
return true;
1129 Handle<String> is_break_point_triggered_symbol =
1130 factory->LookupAsciiSymbol(
"IsBreakPointTriggered");
1131 Handle<JSFunction> check_break_point =
1133 debug_context()->global()->GetPropertyNoExceptionThrown(
1134 *is_break_point_triggered_symbol)));
1137 Handle<Object> break_id = factory->NewNumberFromInt(Debug::break_id());
1140 bool caught_exception;
1141 Handle<Object> argv[] = { break_id, break_point_object };
1143 isolate_->js_builtins_object(),
1149 if (caught_exception || !result->IsBoolean()) {
1154 ASSERT(!result.is_null());
1155 return (*result)->IsTrue();
1160 bool Debug::HasDebugInfo(Handle<SharedFunctionInfo> shared) {
1161 return !shared->debug_info()->IsUndefined();
1167 Handle<DebugInfo> Debug::GetDebugInfo(Handle<SharedFunctionInfo> shared) {
1168 ASSERT(HasDebugInfo(shared));
1169 return Handle<DebugInfo>(DebugInfo::cast(shared->debug_info()));
1173 void Debug::SetBreakPoint(Handle<SharedFunctionInfo> shared,
1174 Handle<Object> break_point_object,
1175 int* source_position) {
1176 HandleScope scope(isolate_);
1178 PrepareForBreakPoints();
1180 if (!EnsureDebugInfo(shared)) {
1185 Handle<DebugInfo> debug_info = GetDebugInfo(shared);
1187 ASSERT(*source_position >= 0);
1190 BreakLocationIterator it(debug_info, SOURCE_BREAK_LOCATIONS);
1191 it.FindBreakLocationFromPosition(*source_position);
1192 it.SetBreakPoint(break_point_object);
1194 *source_position = it.position();
1197 ASSERT(debug_info->GetBreakPointCount() > 0);
1201 void Debug::ClearBreakPoint(Handle<Object> break_point_object) {
1202 HandleScope scope(isolate_);
1204 DebugInfoListNode* node = debug_info_list_;
1205 while (node !=
NULL) {
1206 Object* result = DebugInfo::FindBreakPointInfo(node->debug_info(),
1207 break_point_object);
1208 if (!result->IsUndefined()) {
1210 BreakPointInfo* break_point_info = BreakPointInfo::cast(result);
1211 Handle<DebugInfo> debug_info = node->debug_info();
1212 Handle<SharedFunctionInfo> shared(debug_info->shared());
1213 int source_position = break_point_info->statement_position()->value();
1216 ASSERT(source_position >= 0);
1219 BreakLocationIterator it(debug_info, SOURCE_BREAK_LOCATIONS);
1220 it.FindBreakLocationFromPosition(source_position);
1221 it.ClearBreakPoint(break_point_object);
1225 if (debug_info->GetBreakPointCount() == 0) {
1226 RemoveDebugInfo(debug_info);
1231 node = node->next();
1236 void Debug::ClearAllBreakPoints() {
1237 DebugInfoListNode* node = debug_info_list_;
1238 while (node !=
NULL) {
1240 BreakLocationIterator it(node->debug_info(), ALL_BREAK_LOCATIONS);
1241 it.ClearAllDebugBreak();
1242 node = node->next();
1246 while (debug_info_list_ !=
NULL) {
1247 RemoveDebugInfo(debug_info_list_->debug_info());
1252 void Debug::FloodWithOneShot(Handle<SharedFunctionInfo> shared) {
1253 PrepareForBreakPoints();
1255 if (!EnsureDebugInfo(shared)) {
1261 BreakLocationIterator it(GetDebugInfo(shared), ALL_BREAK_LOCATIONS);
1262 while (!it.Done()) {
1269 void Debug::FloodBoundFunctionWithOneShot(Handle<JSFunction>
function) {
1270 Handle<FixedArray> new_bindings(function->function_bindings());
1273 if (!bindee.is_null() && bindee->IsJSFunction() &&
1275 Handle<SharedFunctionInfo> shared_info(
JSFunction::cast(*bindee)->shared());
1276 Debug::FloodWithOneShot(shared_info);
1281 void Debug::FloodHandlerWithOneShot() {
1283 StackFrame::Id
id = break_frame_id();
1284 if (
id == StackFrame::NO_ID) {
1289 JavaScriptFrame* frame = it.frame();
1290 if (frame->HasHandler()) {
1291 Handle<SharedFunctionInfo> shared =
1292 Handle<SharedFunctionInfo>(
1295 FloodWithOneShot(shared);
1302 void Debug::ChangeBreakOnException(ExceptionBreakType
type,
bool enable) {
1303 if (type == BreakUncaughtException) {
1304 break_on_uncaught_exception_ = enable;
1306 break_on_exception_ = enable;
1311 bool Debug::IsBreakOnException(ExceptionBreakType type) {
1312 if (type == BreakUncaughtException) {
1313 return break_on_uncaught_exception_;
1315 return break_on_exception_;
1320 void Debug::PrepareStep(StepAction step_action,
int step_count) {
1321 HandleScope scope(isolate_);
1323 PrepareForBreakPoints();
1325 ASSERT(Debug::InDebugger());
1328 thread_local_.last_step_action_ = step_action;
1329 if (step_action == StepOut) {
1332 thread_local_.step_count_ = 0;
1334 thread_local_.step_count_ = step_count;
1341 StackFrame::Id
id = break_frame_id();
1342 if (
id == StackFrame::NO_ID) {
1347 JavaScriptFrame* frame = frames_it.frame();
1351 FloodHandlerWithOneShot();
1356 if (!frame->function()->IsJSFunction()) {
1359 frames_it.Advance();
1362 FloodWithOneShot(Handle<SharedFunctionInfo>(function->shared()));
1367 Handle<SharedFunctionInfo> shared =
1369 if (!EnsureDebugInfo(shared)) {
1373 Handle<DebugInfo> debug_info = GetDebugInfo(shared);
1376 BreakLocationIterator it(debug_info, ALL_BREAK_LOCATIONS);
1377 it.FindBreakLocationFromAddress(frame->pc());
1380 bool is_load_or_store =
false;
1381 bool is_inline_cache_stub =
false;
1382 bool is_at_restarted_function =
false;
1383 Handle<Code> call_function_stub;
1385 if (thread_local_.restarter_frame_function_pointer_ ==
NULL) {
1386 if (RelocInfo::IsCodeTarget(it.rinfo()->rmode())) {
1387 bool is_call_target =
false;
1388 Address target = it.rinfo()->target_address();
1390 if (code->is_call_stub() || code->is_keyed_call_stub()) {
1391 is_call_target =
true;
1393 if (code->is_inline_cache_stub()) {
1394 is_inline_cache_stub =
true;
1395 is_load_or_store = !is_call_target;
1399 Code* maybe_call_function_stub = code;
1402 if (it.IsDebugBreak()) {
1403 Address original_target = it.original_rinfo()->target_address();
1404 maybe_call_function_stub =
1407 if (maybe_call_function_stub->kind() ==
Code::STUB &&
1408 maybe_call_function_stub->major_key() == CodeStub::CallFunction) {
1411 call_function_stub = Handle<Code>(maybe_call_function_stub);
1415 is_at_restarted_function =
true;
1419 if (it.IsExit() || step_action == StepOut) {
1420 if (step_action == StepOut) {
1422 while (step_count-- > 0 && !frames_it.done()) {
1423 frames_it.Advance();
1427 frames_it.Advance();
1430 while (!frames_it.done() &&
1432 frames_it.Advance();
1436 if (!frames_it.done()) {
1439 FloodWithOneShot(Handle<SharedFunctionInfo>(function->shared()));
1441 ActivateStepOut(frames_it.frame());
1443 }
else if (!(is_inline_cache_stub || RelocInfo::IsConstructCall(it.rmode()) ||
1444 !call_function_stub.is_null() || is_at_restarted_function)
1445 || step_action == StepNext || step_action == StepMin) {
1449 FloodWithOneShot(shared);
1452 thread_local_.last_statement_position_ =
1453 debug_info->code()->SourceStatementPosition(frame->pc());
1454 thread_local_.last_fp_ = frame->UnpaddedFP();
1458 if (is_at_restarted_function) {
1459 Handle<JSFunction> restarted_function(
1461 Handle<SharedFunctionInfo> restarted_shared(
1462 restarted_function->shared());
1463 FloodWithOneShot(restarted_shared);
1464 }
else if (!call_function_stub.is_null()) {
1472 isolate_->heap()->code_stubs()->SlowReverseLookup(
1473 *call_function_stub));
1475 ASSERT(!(*obj)->IsUndefined());
1481 int call_function_arg_count =
1483 CodeStub::MinorKeyFromKey(key));
1484 ASSERT(call_function_stub->major_key() ==
1485 CodeStub::MajorKeyFromKey(key));
1494 int expressions_count = frame->ComputeExpressionsCount();
1495 ASSERT(expressions_count - 2 - call_function_arg_count >= 0);
1496 Object* fun = frame->GetExpression(
1497 expressions_count - 2 - call_function_arg_count);
1498 if (fun->IsJSFunction()) {
1500 if (js_function->shared()->bound()) {
1501 Debug::FloodBoundFunctionWithOneShot(js_function);
1502 }
else if (!js_function->IsBuiltin()) {
1505 FloodWithOneShot(Handle<SharedFunctionInfo>(js_function->shared()));
1514 FloodWithOneShot(shared);
1516 if (is_load_or_store) {
1521 thread_local_.last_statement_position_ =
1522 debug_info->code()->SourceStatementPosition(frame->pc());
1523 thread_local_.last_fp_ = frame->UnpaddedFP();
1528 ActivateStepIn(frame);
1539 bool Debug::StepNextContinue(BreakLocationIterator* break_location_iterator,
1540 JavaScriptFrame* frame) {
1543 if (thread_local_.last_step_action_ == StepNext ||
1544 thread_local_.last_step_action_ == StepOut) {
1545 if (frame->fp() < thread_local_.last_fp_)
return true;
1550 if (thread_local_.last_step_action_ == StepNext ||
1551 thread_local_.last_step_action_ == StepIn) {
1553 if (break_location_iterator->IsExit())
return false;
1556 int current_statement_position =
1557 break_location_iterator->code()->SourceStatementPosition(frame->pc());
1558 return thread_local_.last_fp_ == frame->UnpaddedFP() &&
1559 thread_local_.last_statement_position_ == current_statement_position;
1569 bool Debug::IsDebugBreak(
Address addr) {
1577 bool Debug::IsSourceBreakStub(Code* code) {
1578 CodeStub::Major major_key = CodeStub::GetMajorKey(code);
1579 return major_key == CodeStub::CallFunction;
1585 bool Debug::IsBreakStub(Code* code) {
1586 CodeStub::Major major_key = CodeStub::GetMajorKey(code);
1587 return major_key == CodeStub::CallFunction;
1592 Handle<Code> Debug::FindDebugBreak(Handle<Code> code, RelocInfo::Mode mode) {
1593 Isolate* isolate = Isolate::Current();
1597 if (code->is_inline_cache_stub()) {
1598 switch (code->kind()) {
1601 return isolate->stub_cache()->ComputeCallDebugBreak(
1602 code->arguments_count(), code->kind());
1605 return isolate->builtins()->LoadIC_DebugBreak();
1608 return isolate->builtins()->StoreIC_DebugBreak();
1611 return isolate->builtins()->KeyedLoadIC_DebugBreak();
1614 return isolate->builtins()->KeyedStoreIC_DebugBreak();
1620 if (RelocInfo::IsConstructCall(mode)) {
1621 if (code->has_function_cache()) {
1622 return isolate->builtins()->CallConstructStub_Recording_DebugBreak();
1624 return isolate->builtins()->CallConstructStub_DebugBreak();
1628 ASSERT(code->major_key() == CodeStub::CallFunction);
1629 if (code->has_function_cache()) {
1630 return isolate->builtins()->CallFunctionStub_Recording_DebugBreak();
1632 return isolate->builtins()->CallFunctionStub_DebugBreak();
1642 Handle<Object> Debug::GetSourceBreakLocations(
1643 Handle<SharedFunctionInfo> shared) {
1644 Isolate* isolate = Isolate::Current();
1645 Heap* heap = isolate->heap();
1646 if (!HasDebugInfo(shared))
return Handle<Object>(heap->undefined_value());
1647 Handle<DebugInfo> debug_info = GetDebugInfo(shared);
1648 if (debug_info->GetBreakPointCount() == 0) {
1649 return Handle<Object>(heap->undefined_value());
1651 Handle<FixedArray> locations =
1652 isolate->factory()->NewFixedArray(debug_info->GetBreakPointCount());
1654 for (
int i = 0; i < debug_info->break_points()->length(); i++) {
1655 if (!debug_info->break_points()->get(i)->IsUndefined()) {
1656 BreakPointInfo* break_point_info =
1657 BreakPointInfo::cast(debug_info->break_points()->get(i));
1658 if (break_point_info->GetBreakPointCount() > 0) {
1659 locations->set(count++, break_point_info->statement_position());
1667 void Debug::NewBreak(StackFrame::Id break_frame_id) {
1668 thread_local_.break_frame_id_ = break_frame_id;
1669 thread_local_.break_id_ = ++thread_local_.break_count_;
1673 void Debug::SetBreak(StackFrame::Id break_frame_id,
int break_id) {
1674 thread_local_.break_frame_id_ = break_frame_id;
1675 thread_local_.break_id_ = break_id;
1680 void Debug::HandleStepIn(Handle<JSFunction>
function,
1681 Handle<Object> holder,
1683 bool is_constructor) {
1686 StackFrameIterator it;
1689 if (is_constructor) {
1690 ASSERT(it.frame()->is_construct());
1693 fp = it.frame()->fp();
1698 if (fp == step_in_fp()) {
1699 if (function->shared()->bound()) {
1701 Debug::FloodBoundFunctionWithOneShot(
function);
1702 }
else if (!function->IsBuiltin()) {
1704 if (function->shared()->code() ==
1705 Isolate::Current()->builtins()->builtin(Builtins::kFunctionApply) ||
1706 function->shared()->code() ==
1707 Isolate::Current()->builtins()->builtin(Builtins::kFunctionCall)) {
1712 if (!holder.is_null() && holder->IsJSFunction() &&
1714 Handle<SharedFunctionInfo> shared_info(
1716 Debug::FloodWithOneShot(shared_info);
1719 Debug::FloodWithOneShot(Handle<SharedFunctionInfo>(function->shared()));
1726 void Debug::ClearStepping() {
1734 thread_local_.step_count_ = 0;
1740 void Debug::ClearOneShot() {
1745 DebugInfoListNode* node = debug_info_list_;
1746 while (node !=
NULL) {
1747 BreakLocationIterator it(node->debug_info(), ALL_BREAK_LOCATIONS);
1748 while (!it.Done()) {
1752 node = node->next();
1757 void Debug::ActivateStepIn(
StackFrame* frame) {
1758 ASSERT(!StepOutActive());
1759 thread_local_.step_into_fp_ = frame->UnpaddedFP();
1763 void Debug::ClearStepIn() {
1764 thread_local_.step_into_fp_ = 0;
1768 void Debug::ActivateStepOut(
StackFrame* frame) {
1770 thread_local_.step_out_fp_ = frame->UnpaddedFP();
1774 void Debug::ClearStepOut() {
1775 thread_local_.step_out_fp_ = 0;
1779 void Debug::ClearStepNext() {
1780 thread_local_.last_step_action_ = StepNone;
1781 thread_local_.last_statement_position_ = RelocInfo::kNoPosition;
1782 thread_local_.last_fp_ = 0;
1795 static bool CompileFullCodeForDebugging(Handle<JSFunction>
function,
1796 Handle<Code> current_code) {
1797 ASSERT(!current_code->has_debug_break_slots());
1799 CompilationInfo info(
function);
1800 info.MarkCompilingForDebugging(current_code);
1801 ASSERT(!info.shared_info()->is_compiled());
1802 ASSERT(!info.isolate()->has_pending_exception());
1807 ASSERT(result != Isolate::Current()->has_pending_exception());
1808 info.isolate()->clear_pending_exception();
1811 Handle<Code> new_code(function->shared()->code());
1812 ASSERT(new_code->has_debug_break_slots());
1813 ASSERT(current_code->is_compiled_optimizable() ==
1814 new_code->is_compiled_optimizable());
1821 static void CollectActiveFunctionsFromThread(
1823 ThreadLocalTop* top,
1824 List<Handle<JSFunction> >* active_functions,
1825 Object* active_code_marker) {
1831 JavaScriptFrame* frame = it.frame();
1832 if (frame->is_optimized()) {
1834 frame->GetFunctions(&functions);
1835 for (
int i = 0; i < functions.length(); i++) {
1836 JSFunction*
function = functions[i];
1837 active_functions->Add(Handle<JSFunction>(
function));
1838 function->shared()->code()->set_gc_metadata(active_code_marker);
1840 }
else if (frame->function()->IsJSFunction()) {
1843 active_functions->Add(Handle<JSFunction>(
function));
1844 function->shared()->code()->set_gc_metadata(active_code_marker);
1850 static void RedirectActivationsToRecompiledCodeOnThread(
1852 ThreadLocalTop* top) {
1854 JavaScriptFrame* frame = it.frame();
1856 if (frame->is_optimized() || !frame->function()->IsJSFunction())
continue;
1862 Handle<Code> frame_code(frame->LookupCode());
1863 if (frame_code->has_debug_break_slots())
continue;
1865 Handle<Code> new_code(function->shared()->code());
1867 !new_code->has_debug_break_slots()) {
1871 intptr_t delta = frame->pc() - frame_code->instruction_start();
1872 int debug_break_slot_count = 0;
1873 int mask = RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT);
1874 for (RelocIterator it(*new_code, mask); !it.done(); it.next()) {
1877 RelocInfo* info = it.rinfo();
1878 int debug_break_slot_bytes =
1880 intptr_t new_delta =
1882 new_code->instruction_start() -
1883 debug_break_slot_bytes;
1884 if (new_delta > delta) {
1890 debug_break_slot_count++;
1892 int debug_break_slot_bytes =
1894 if (FLAG_trace_deopt) {
1899 reinterpret_cast<intptr_t>(
1900 frame_code->instruction_start()),
1901 reinterpret_cast<intptr_t>(
1902 frame_code->instruction_start()) +
1903 frame_code->instruction_size(),
1904 frame_code->instruction_size(),
1905 reinterpret_cast<intptr_t
>(new_code->instruction_start()),
1906 reinterpret_cast<intptr_t>(new_code->instruction_start()) +
1907 new_code->instruction_size(),
1908 new_code->instruction_size(),
1909 reinterpret_cast<intptr_t
>(frame->pc()),
1910 reinterpret_cast<intptr_t>(new_code->instruction_start()) +
1911 delta + debug_break_slot_bytes);
1917 new_code->instruction_start() + delta + debug_break_slot_bytes);
1922 class ActiveFunctionsCollector :
public ThreadVisitor {
1924 explicit ActiveFunctionsCollector(List<Handle<JSFunction> >* active_functions,
1925 Object* active_code_marker)
1926 : active_functions_(active_functions),
1927 active_code_marker_(active_code_marker) { }
1929 void VisitThread(Isolate* isolate, ThreadLocalTop* top) {
1930 CollectActiveFunctionsFromThread(isolate,
1933 active_code_marker_);
1937 List<Handle<JSFunction> >* active_functions_;
1938 Object* active_code_marker_;
1942 class ActiveFunctionsRedirector :
public ThreadVisitor {
1944 void VisitThread(Isolate* isolate, ThreadLocalTop* top) {
1945 RedirectActivationsToRecompiledCodeOnThread(isolate, top);
1950 void Debug::PrepareForBreakPoints() {
1953 if (!has_break_points_) {
1956 Handle<Code> lazy_compile =
1957 Handle<Code>(isolate_->builtins()->builtin(Builtins::kLazyCompile));
1961 List<Handle<JSFunction> > active_functions(100);
1967 "preparing for breakpoints");
1971 AssertNoAllocation no_allocation;
1973 Object* active_code_marker = isolate_->heap()->the_hole_value();
1975 CollectActiveFunctionsFromThread(isolate_,
1976 isolate_->thread_local_top(),
1978 active_code_marker);
1979 ActiveFunctionsCollector active_functions_collector(&active_functions,
1980 active_code_marker);
1981 isolate_->thread_manager()->IterateArchivedThreads(
1982 &active_functions_collector);
1987 HeapIterator iterator;
1988 HeapObject* obj =
NULL;
1989 while (((obj = iterator.next()) !=
NULL)) {
1990 if (obj->IsJSFunction()) {
1992 SharedFunctionInfo* shared =
function->shared();
1993 if (shared->allows_lazy_compilation() &&
1994 shared->script()->IsScript() &&
1996 !
function->code()->has_debug_break_slots() &&
1997 shared->code()->gc_metadata() != active_code_marker) {
1998 function->set_code(*lazy_compile);
1999 function->shared()->set_code(*lazy_compile);
2005 for (
int i = 0; i < active_functions.length(); i++) {
2006 Handle<JSFunction>
function = active_functions[i];
2007 function->shared()->code()->set_gc_metadata(
Smi::FromInt(0));
2013 for (
int i = 0; i < active_functions.length(); i++) {
2014 Handle<JSFunction>
function = active_functions[i];
2015 Handle<SharedFunctionInfo> shared(function->shared());
2018 function->code()->has_debug_break_slots()) {
2024 if (shared->is_toplevel() ||
2025 !shared->allows_lazy_compilation() ||
2032 if (!shared->code()->has_debug_break_slots()) {
2035 Handle<Code> current_code(function->shared()->code());
2037 shared->set_code(*lazy_compile);
2038 bool prev_force_debugger_active =
2039 isolate_->debugger()->force_debugger_active();
2040 isolate_->debugger()->set_force_debugger_active(
true);
2042 CompileFullCodeForDebugging(
function, current_code);
2043 isolate_->debugger()->set_force_debugger_active(
2044 prev_force_debugger_active);
2045 if (!shared->is_compiled()) {
2046 shared->set_code(*current_code);
2052 function->set_code(shared->code());
2055 RedirectActivationsToRecompiledCodeOnThread(isolate_,
2056 isolate_->thread_local_top());
2058 ActiveFunctionsRedirector active_functions_redirector;
2059 isolate_->thread_manager()->IterateArchivedThreads(
2060 &active_functions_redirector);
2066 bool Debug::EnsureDebugInfo(Handle<SharedFunctionInfo> shared) {
2068 if (HasDebugInfo(shared)) {
2069 ASSERT(shared->is_compiled());
2079 Handle<DebugInfo> debug_info =
FACTORY->NewDebugInfo(shared);
2082 DebugInfoListNode* node =
new DebugInfoListNode(*debug_info);
2083 node->set_next(debug_info_list_);
2084 debug_info_list_ = node;
2087 has_break_points_ =
true;
2093 void Debug::RemoveDebugInfo(Handle<DebugInfo> debug_info) {
2096 DebugInfoListNode* prev =
NULL;
2097 DebugInfoListNode* current = debug_info_list_;
2098 while (current !=
NULL) {
2099 if (*current->debug_info() == *debug_info) {
2102 debug_info_list_ = current->next();
2104 prev->set_next(current->next());
2106 current->debug_info()->shared()->set_debug_info(
2107 isolate_->heap()->undefined_value());
2112 has_break_points_ = debug_info_list_ !=
NULL;
2118 current = current->next();
2124 void Debug::SetAfterBreakTarget(JavaScriptFrame* frame) {
2125 HandleScope scope(isolate_);
2127 PrepareForBreakPoints();
2130 Handle<SharedFunctionInfo> shared =
2132 if (!EnsureDebugInfo(shared)) {
2136 Handle<DebugInfo> debug_info = GetDebugInfo(shared);
2137 Handle<Code> code(debug_info->code());
2138 Handle<Code> original_code(debug_info->original_code());
2141 Handle<Code> frame_code(frame->LookupCode());
2142 ASSERT(frame_code.is_identical_to(code));
2151 bool at_js_return =
false;
2152 bool break_at_js_return_active =
false;
2153 bool at_debug_break_slot =
false;
2154 RelocIterator it(debug_info->code());
2155 while (!it.done() && !at_js_return && !at_debug_break_slot) {
2156 if (RelocInfo::IsJSReturn(it.rinfo()->rmode())) {
2157 at_js_return = (it.rinfo()->pc() ==
2159 break_at_js_return_active = it.rinfo()->IsPatchedReturnSequence();
2161 if (RelocInfo::IsDebugBreakSlot(it.rinfo()->rmode())) {
2162 at_debug_break_slot = (it.rinfo()->pc() ==
2174 if (break_at_js_return_active) {
2175 addr += original_code->instruction_start() - code->instruction_start();
2179 thread_local_.after_break_target_ =
2181 }
else if (at_debug_break_slot) {
2194 addr += original_code->instruction_start() - code->instruction_start();
2209 bool Debug::IsBreakAtReturn(JavaScriptFrame* frame) {
2210 HandleScope scope(isolate_);
2215 if (!has_break_points_) {
2219 PrepareForBreakPoints();
2222 Handle<SharedFunctionInfo> shared =
2224 if (!EnsureDebugInfo(shared)) {
2228 Handle<DebugInfo> debug_info = GetDebugInfo(shared);
2229 Handle<Code> code(debug_info->code());
2232 Handle<Code> frame_code(frame->LookupCode());
2233 ASSERT(frame_code.is_identical_to(code));
2240 RelocIterator it(debug_info->code());
2241 while (!it.done()) {
2242 if (RelocInfo::IsJSReturn(it.rinfo()->rmode())) {
2243 return (it.rinfo()->pc() ==
2252 void Debug::FramesHaveBeenDropped(StackFrame::Id new_break_frame_id,
2254 Object** restarter_frame_function_pointer) {
2255 thread_local_.frame_drop_mode_ = mode;
2256 thread_local_.break_frame_id_ = new_break_frame_id;
2257 thread_local_.restarter_frame_function_pointer_ =
2258 restarter_frame_function_pointer;
2262 const int Debug::FramePaddingLayout::kInitialSize = 1;
2266 const int Debug::FramePaddingLayout::kPaddingValue = kInitialSize + 1;
2269 bool Debug::IsDebugGlobal(GlobalObject* global) {
2270 return IsLoaded() && global == debug_context()->global();
2274 void Debug::ClearMirrorCache() {
2275 PostponeInterruptsScope postpone(isolate_);
2276 HandleScope scope(isolate_);
2277 ASSERT(isolate_->context() == *Debug::debug_context());
2280 Handle<String> function_name =
2281 isolate_->factory()->LookupSymbol(
CStrVector(
"ClearMirrorCache"));
2282 Handle<Object> fun(Isolate::Current()->global()->GetPropertyNoExceptionThrown(
2284 ASSERT(fun->IsJSFunction());
2285 bool caught_exception;
2287 Handle<JSObject>(Debug::debug_context()->global()),
2288 0,
NULL, &caught_exception);
2292 void Debug::CreateScriptCache() {
2293 Heap* heap = isolate_->heap();
2294 HandleScope scope(isolate_);
2302 "Debug::CreateScriptCache");
2305 script_cache_ =
new ScriptCache();
2309 HeapIterator iterator;
2310 AssertNoAllocation no_allocation;
2312 for (HeapObject* obj = iterator.next(); obj !=
NULL; obj = iterator.next()) {
2321 void Debug::DestroyScriptCache() {
2323 if (script_cache_ !=
NULL) {
2324 delete script_cache_;
2325 script_cache_ =
NULL;
2330 void Debug::AddScriptToScriptCache(Handle<Script> script) {
2331 if (script_cache_ !=
NULL) {
2332 script_cache_->Add(script);
2337 Handle<FixedArray> Debug::GetLoadedScripts() {
2340 if (script_cache_ ==
NULL) {
2341 CreateScriptCache();
2346 if (script_cache_ ==
NULL) {
2347 isolate_->factory()->NewFixedArray(0);
2353 "Debug::GetLoadedScripts");
2356 return script_cache_->GetScripts();
2360 void Debug::AfterGarbageCollection() {
2362 if (script_cache_ !=
NULL) {
2363 script_cache_->ProcessCollectedScripts();
2368 Debugger::Debugger(Isolate* isolate)
2369 : debugger_access_(isolate->debugger_access()),
2370 event_listener_(Handle<
Object>()),
2371 event_listener_data_(Handle<
Object>()),
2372 compiling_natives_(
false),
2373 is_loading_debugger_(
false),
2374 never_unload_debugger_(
false),
2375 force_debugger_active_(
false),
2376 message_handler_(
NULL),
2377 debugger_unload_pending_(
false),
2378 host_dispatch_handler_(
NULL),
2379 dispatch_handler_access_(OS::CreateMutex()),
2380 debug_message_dispatch_handler_(
NULL),
2381 message_dispatch_helper_thread_(
NULL),
2382 host_dispatch_micros_(100 * 1000),
2384 command_queue_(isolate->logger(), kQueueInitialSize),
2385 command_received_(OS::CreateSemaphore(0)),
2386 event_command_queue_(isolate->logger(), kQueueInitialSize),
2391 Debugger::~Debugger() {
2392 delete dispatch_handler_access_;
2393 dispatch_handler_access_ = 0;
2394 delete command_received_;
2395 command_received_ = 0;
2399 Handle<Object> Debugger::MakeJSObject(Vector<const char> constructor_name,
2401 Handle<Object> argv[],
2402 bool* caught_exception) {
2403 ASSERT(isolate_->context() == *isolate_->debug()->debug_context());
2406 Handle<String> constructor_str =
2407 isolate_->factory()->LookupSymbol(constructor_name);
2408 Handle<Object> constructor(
2409 isolate_->global()->GetPropertyNoExceptionThrown(*constructor_str));
2410 ASSERT(constructor->IsJSFunction());
2411 if (!constructor->IsJSFunction()) {
2412 *caught_exception =
true;
2413 return isolate_->factory()->undefined_value();
2416 Handle<JSFunction>::cast(constructor),
2417 Handle<JSObject>(isolate_->debug()->debug_context()->global()),
2425 Handle<Object> Debugger::MakeExecutionState(
bool* caught_exception) {
2427 Handle<Object> break_id = isolate_->factory()->NewNumberFromInt(
2428 isolate_->debug()->break_id());
2429 Handle<Object> argv[] = { break_id };
2430 return MakeJSObject(
CStrVector(
"MakeExecutionState"),
2437 Handle<Object> Debugger::MakeBreakEvent(Handle<Object> exec_state,
2438 Handle<Object> break_points_hit,
2439 bool* caught_exception) {
2441 Handle<Object> argv[] = { exec_state, break_points_hit };
2442 return MakeJSObject(
CStrVector(
"MakeBreakEvent"),
2449 Handle<Object> Debugger::MakeExceptionEvent(Handle<Object> exec_state,
2450 Handle<Object> exception,
2452 bool* caught_exception) {
2453 Factory* factory = isolate_->factory();
2455 Handle<Object> argv[] = { exec_state,
2457 factory->ToBoolean(uncaught) };
2458 return MakeJSObject(
CStrVector(
"MakeExceptionEvent"),
2465 Handle<Object> Debugger::MakeNewFunctionEvent(Handle<Object>
function,
2466 bool* caught_exception) {
2468 Handle<Object> argv[] = {
function };
2469 return MakeJSObject(
CStrVector(
"MakeNewFunctionEvent"),
2476 Handle<Object> Debugger::MakeCompileEvent(Handle<Script> script,
2478 bool* caught_exception) {
2479 Factory* factory = isolate_->factory();
2481 Handle<Object> exec_state = MakeExecutionState(caught_exception);
2483 Handle<Object> argv[] = { exec_state,
2485 factory->ToBoolean(before) };
2486 return MakeJSObject(
CStrVector(
"MakeCompileEvent"),
2493 Handle<Object> Debugger::MakeScriptCollectedEvent(
int id,
2494 bool* caught_exception) {
2496 Handle<Object> exec_state = MakeExecutionState(caught_exception);
2497 Handle<Object> id_object = Handle<Smi>(
Smi::FromInt(
id));
2498 Handle<Object> argv[] = { exec_state, id_object };
2500 return MakeJSObject(
CStrVector(
"MakeScriptCollectedEvent"),
2507 void Debugger::OnException(Handle<Object> exception,
bool uncaught) {
2508 HandleScope scope(isolate_);
2509 Debug* debug = isolate_->debug();
2512 if (debug->InDebugger())
return;
2518 if (!(debug->break_on_uncaught_exception() ||
2519 debug->break_on_exception()))
return;
2522 if (!debug->break_on_exception())
return;
2526 EnterDebugger debugger;
2527 if (debugger.FailedToEnter())
return;
2530 debug->ClearStepping();
2532 bool caught_exception =
false;
2533 Handle<Object> exec_state = MakeExecutionState(&caught_exception);
2534 Handle<Object> event_data;
2535 if (!caught_exception) {
2536 event_data = MakeExceptionEvent(exec_state, exception, uncaught,
2540 if (caught_exception) {
2545 ProcessDebugEvent(
v8::Exception, Handle<JSObject>::cast(event_data),
false);
2550 void Debugger::OnDebugBreak(Handle<Object> break_points_hit,
2551 bool auto_continue) {
2552 HandleScope scope(isolate_);
2555 ASSERT(isolate_->context() == *isolate_->debug()->debug_context());
2558 if (!Debugger::EventActive(
v8::Break))
return;
2561 ASSERT(isolate_->context() == *isolate_->debug()->debug_context());
2564 bool caught_exception =
false;
2565 Handle<Object> exec_state = MakeExecutionState(&caught_exception);
2566 Handle<Object> event_data;
2567 if (!caught_exception) {
2568 event_data = MakeBreakEvent(exec_state, break_points_hit,
2572 if (caught_exception) {
2578 Handle<JSObject>::cast(event_data),
2583 void Debugger::OnBeforeCompile(Handle<Script> script) {
2584 HandleScope scope(isolate_);
2587 if (isolate_->debug()->InDebugger())
return;
2588 if (compiling_natives())
return;
2592 EnterDebugger debugger;
2593 if (debugger.FailedToEnter())
return;
2596 bool caught_exception =
false;
2597 Handle<Object> event_data = MakeCompileEvent(script,
true, &caught_exception);
2599 if (caught_exception) {
2605 Handle<JSObject>::cast(event_data),
2611 void Debugger::OnAfterCompile(Handle<Script> script,
2612 AfterCompileFlags after_compile_flags) {
2613 HandleScope scope(isolate_);
2614 Debug* debug = isolate_->debug();
2617 debug->AddScriptToScriptCache(script);
2620 if (!IsDebuggerActive())
return;
2623 if (compiling_natives())
return;
2626 bool in_debugger = debug->InDebugger();
2629 EnterDebugger debugger;
2630 if (debugger.FailedToEnter())
return;
2636 Handle<String> update_script_break_points_symbol =
2637 isolate_->factory()->LookupAsciiSymbol(
"UpdateScriptBreakPoints");
2638 Handle<Object> update_script_break_points =
2639 Handle<Object>(debug->debug_context()->global()->
2640 GetPropertyNoExceptionThrown(*update_script_break_points_symbol));
2641 if (!update_script_break_points->IsJSFunction()) {
2644 ASSERT(update_script_break_points->IsJSFunction());
2651 bool caught_exception;
2652 Handle<Object> argv[] = { wrapper };
2654 Isolate::Current()->js_builtins_object(),
2658 if (caught_exception) {
2662 if (in_debugger && (after_compile_flags & SEND_WHEN_DEBUGGING) == 0)
return;
2666 Handle<Object> event_data = MakeCompileEvent(script,
2670 if (caught_exception) {
2675 Handle<JSObject>::cast(event_data),
2680 void Debugger::OnScriptCollected(
int id) {
2681 HandleScope scope(isolate_);
2684 if (!IsDebuggerActive())
return;
2688 EnterDebugger debugger;
2689 if (debugger.FailedToEnter())
return;
2692 bool caught_exception =
false;
2693 Handle<Object> event_data = MakeScriptCollectedEvent(
id,
2696 if (caught_exception) {
2702 Handle<JSObject>::cast(event_data),
2708 Handle<JSObject> event_data,
2709 bool auto_continue) {
2710 HandleScope scope(isolate_);
2713 if (!auto_continue) {
2714 isolate_->debug()->clear_interrupt_pending(
DEBUGBREAK);
2718 bool caught_exception =
false;
2719 Handle<Object> exec_state = MakeExecutionState(&caught_exception);
2720 if (caught_exception) {
2724 if (message_handler_ !=
NULL) {
2725 NotifyMessageHandler(event,
2726 Handle<JSObject>::cast(exec_state),
2733 if ((event !=
v8::Break || !auto_continue) && !event_listener_.is_null()) {
2734 CallEventCallback(event, exec_state, event_data,
NULL);
2738 while (!event_command_queue_.IsEmpty()) {
2739 CommandMessage command = event_command_queue_.Get();
2740 if (!event_listener_.is_null()) {
2744 command.client_data());
2753 Handle<Object> exec_state,
2754 Handle<Object> event_data,
2756 if (event_listener_->IsForeign()) {
2757 CallCEventCallback(event, exec_state, event_data, client_data);
2759 CallJSEventCallback(event, exec_state, event_data);
2765 Handle<Object> exec_state,
2766 Handle<Object> event_data,
2768 Handle<Foreign> callback_obj(Handle<Foreign>::cast(event_listener_));
2770 FUNCTION_CAST<v8::Debug::EventCallback2>(
2771 callback_obj->foreign_address());
2772 EventDetailsImpl event_details(
2774 Handle<JSObject>::cast(exec_state),
2775 Handle<JSObject>::cast(event_data),
2776 event_listener_data_,
2778 callback(event_details);
2783 Handle<Object> exec_state,
2784 Handle<Object> event_data) {
2785 ASSERT(event_listener_->IsJSFunction());
2786 Handle<JSFunction> fun(Handle<JSFunction>::cast(event_listener_));
2789 Handle<Object> argv[] = { Handle<Object>(
Smi::FromInt(event)),
2792 event_listener_data_ };
2793 bool caught_exception;
2803 Handle<Context> Debugger::GetDebugContext() {
2804 never_unload_debugger_ =
true;
2805 EnterDebugger debugger;
2806 return isolate_->debug()->debug_context();
2810 void Debugger::UnloadDebugger() {
2811 Debug* debug = isolate_->debug();
2814 debug->ClearAllBreakPoints();
2817 if (!never_unload_debugger_) {
2822 debugger_unload_pending_ =
false;
2827 Handle<JSObject> exec_state,
2828 Handle<JSObject> event_data,
2829 bool auto_continue) {
2830 HandleScope scope(isolate_);
2832 if (!isolate_->debug()->Load())
return;
2835 bool sendEventMessage =
false;
2839 sendEventMessage = !auto_continue;
2842 sendEventMessage =
true;
2847 sendEventMessage =
true;
2850 sendEventMessage =
true;
2861 ASSERT(isolate_->debug()->InDebugger());
2866 if (sendEventMessage) {
2867 MessageImpl message = MessageImpl::NewEvent(
2870 Handle<JSObject>::cast(exec_state),
2871 Handle<JSObject>::cast(event_data));
2872 InvokeMessageHandler(message);
2897 static const int kArgc = 1;
2906 bool running = auto_continue;
2911 if (Debugger::host_dispatch_handler_) {
2913 if (!command_received_->Wait(host_dispatch_micros_)) {
2915 Debugger::host_dispatch_handler_();
2920 command_received_->Wait();
2924 CommandMessage command = command_queue_.Get();
2925 isolate_->logger()->DebugTag(
2926 "Got request from command queue, in interactive loop.");
2927 if (!Debugger::IsDebuggerActive()) {
2942 command.text().length());
2943 static const int kArgc = 1;
2958 if (FLAG_trace_debug_json) {
2966 static const int kArgc = 1;
2970 running = running_val->
ToBoolean()->Value();
2974 response = try_catch.
Exception()->ToString();
2978 MessageImpl message = MessageImpl::NewResponse(
2981 Handle<JSObject>::cast(exec_state),
2982 Handle<JSObject>::cast(event_data),
2984 command.client_data());
2985 InvokeMessageHandler(message);
2991 if (running && !HasCommands()) {
2998 void Debugger::SetEventListener(Handle<Object> callback,
2999 Handle<Object> data) {
3000 HandleScope scope(isolate_);
3001 GlobalHandles* global_handles = isolate_->global_handles();
3005 if (!event_listener_.is_null()) {
3006 global_handles->Destroy(
3007 reinterpret_cast<Object**>(event_listener_.location()));
3008 event_listener_ = Handle<Object>();
3010 if (!event_listener_data_.is_null()) {
3011 global_handles->Destroy(
3012 reinterpret_cast<Object**>(event_listener_data_.location()));
3013 event_listener_data_ = Handle<Object>();
3018 if (!callback->IsUndefined() && !callback->IsNull()) {
3020 global_handles->Create(*callback));
3021 if (data.is_null()) {
3022 data = isolate_->factory()->undefined_value();
3025 global_handles->Create(*data));
3033 ScopedLock with(debugger_access_);
3035 message_handler_ = handler;
3037 if (handler ==
NULL) {
3040 if (isolate_->debug()->InDebugger()) {
3041 ProcessCommand(Vector<const uint16_t>::empty());
3047 void Debugger::ListenersChanged() {
3048 if (IsDebuggerActive()) {
3050 isolate_->compilation_cache()->Disable();
3051 debugger_unload_pending_ =
false;
3053 isolate_->compilation_cache()->Enable();
3056 debugger_unload_pending_ =
true;
3063 host_dispatch_handler_ = handler;
3064 host_dispatch_micros_ = period * 1000;
3068 void Debugger::SetDebugMessageDispatchHandler(
3070 ScopedLock with(dispatch_handler_access_);
3071 debug_message_dispatch_handler_ = handler;
3073 if (provide_locker && message_dispatch_helper_thread_ ==
NULL) {
3074 message_dispatch_helper_thread_ =
new MessageDispatchHelperThread(isolate_);
3075 message_dispatch_helper_thread_->Start();
3082 void Debugger::InvokeMessageHandler(MessageImpl message) {
3083 ScopedLock with(debugger_access_);
3085 if (message_handler_ !=
NULL) {
3086 message_handler_(message);
3095 void Debugger::ProcessCommand(Vector<const uint16_t> command,
3098 CommandMessage message = CommandMessage::New(
3099 Vector<uint16_t>(const_cast<uint16_t*>(command.start()),
3102 isolate_->logger()->DebugTag(
"Put command on command_queue.");
3103 command_queue_.Put(message);
3104 command_received_->Signal();
3107 if (!isolate_->debug()->InDebugger()) {
3108 isolate_->stack_guard()->DebugCommand();
3111 MessageDispatchHelperThread* dispatch_thread;
3113 ScopedLock with(dispatch_handler_access_);
3114 dispatch_thread = message_dispatch_helper_thread_;
3117 if (dispatch_thread ==
NULL) {
3118 CallMessageDispatchHandler();
3120 dispatch_thread->Schedule();
3125 bool Debugger::HasCommands() {
3126 return !command_queue_.IsEmpty();
3131 CommandMessage message = CommandMessage::New(Vector<uint16_t>(), client_data);
3132 event_command_queue_.Put(message);
3135 if (!isolate_->debug()->InDebugger()) {
3136 isolate_->stack_guard()->DebugCommand();
3141 bool Debugger::IsDebuggerActive() {
3142 ScopedLock with(debugger_access_);
3144 return message_handler_ !=
NULL ||
3145 !event_listener_.is_null() ||
3146 force_debugger_active_;
3150 Handle<Object> Debugger::Call(Handle<JSFunction> fun,
3151 Handle<Object> data,
3152 bool* pending_exception) {
3154 Debugger::never_unload_debugger_ =
true;
3157 EnterDebugger debugger;
3158 if (debugger.FailedToEnter()) {
3159 return isolate_->factory()->undefined_value();
3163 bool caught_exception =
false;
3164 Handle<Object> exec_state = MakeExecutionState(&caught_exception);
3165 if (caught_exception) {
3166 return isolate_->factory()->undefined_value();
3169 Handle<Object> argv[] = { exec_state, data };
3172 Handle<Object>(isolate_->debug()->debug_context_->global_proxy()),
3185 bool Debugger::StartAgent(
const char* name,
int port,
3186 bool wait_for_connection) {
3187 ASSERT(Isolate::Current() == isolate_);
3188 if (wait_for_connection) {
3195 Debugger::message_handler_ = StubMessageHandler2;
3200 if (agent_ ==
NULL) {
3201 agent_ =
new DebuggerAgent(name, port);
3211 void Debugger::StopAgent() {
3212 ASSERT(Isolate::Current() == isolate_);
3213 if (agent_ !=
NULL) {
3222 void Debugger::WaitForAgent() {
3223 ASSERT(Isolate::Current() == isolate_);
3225 agent_->WaitUntilListening();
3229 void Debugger::CallMessageDispatchHandler() {
3232 ScopedLock with(dispatch_handler_access_);
3233 handler = Debugger::debug_message_dispatch_handler_;
3235 if (handler !=
NULL) {
3241 EnterDebugger::EnterDebugger()
3242 : isolate_(Isolate::Current()),
3243 prev_(isolate_->debug()->debugger_entry()),
3245 has_js_frames_(!it_.done()),
3247 Debug* debug = isolate_->debug();
3252 debug->set_debugger_entry(
this);
3255 break_id_ = debug->break_id();
3256 break_frame_id_ = debug->break_frame_id();
3260 if (has_js_frames_) {
3261 debug->NewBreak(it_.frame()->id());
3263 debug->NewBreak(StackFrame::NO_ID);
3267 load_failed_ = !debug->Load();
3268 if (!load_failed_) {
3271 isolate_->set_context(*debug->debug_context());
3276 EnterDebugger::~EnterDebugger() {
3277 ASSERT(Isolate::Current() == isolate_);
3278 Debug* debug = isolate_->debug();
3281 debug->SetBreak(break_frame_id_, break_id_);
3284 if (!load_failed_ && prev_ ==
NULL) {
3289 if (!isolate_->has_pending_exception()) {
3292 if (isolate_->stack_guard()->IsDebugBreak()) {
3294 isolate_->stack_guard()->Continue(
DEBUGBREAK);
3296 debug->ClearMirrorCache();
3301 if (debug->is_interrupt_pending(
PREEMPT)) {
3304 debug->clear_interrupt_pending(
PREEMPT);
3305 isolate_->stack_guard()->Preempt();
3307 if (debug->is_interrupt_pending(
DEBUGBREAK)) {
3309 isolate_->stack_guard()->DebugBreak();
3314 if (isolate_->debugger()->HasCommands()) {
3315 isolate_->stack_guard()->DebugCommand();
3319 if (!isolate_->debugger()->IsDebuggerActive()) {
3320 isolate_->debugger()->UnloadDebugger();
3325 debug->set_debugger_entry(prev_);
3329 MessageImpl MessageImpl::NewEvent(
DebugEvent event,
3331 Handle<JSObject> exec_state,
3332 Handle<JSObject> event_data) {
3333 MessageImpl message(
true, event, running,
3334 exec_state, event_data, Handle<String>(),
NULL);
3339 MessageImpl MessageImpl::NewResponse(
DebugEvent event,
3341 Handle<JSObject> exec_state,
3342 Handle<JSObject> event_data,
3343 Handle<String> response_json,
3345 MessageImpl message(
false, event, running,
3346 exec_state, event_data, response_json, client_data);
3351 MessageImpl::MessageImpl(
bool is_event,
3354 Handle<JSObject> exec_state,
3355 Handle<JSObject> event_data,
3356 Handle<String> response_json,
3358 : is_event_(is_event),
3361 exec_state_(exec_state),
3362 event_data_(event_data),
3363 response_json_(response_json),
3364 client_data_(client_data) {}
3367 bool MessageImpl::IsEvent()
const {
3372 bool MessageImpl::IsResponse()
const {
3382 bool MessageImpl::WillStartRunning()
const {
3402 Handle<Object> fun =
GetProperty(event_data_,
"toJSONProtocol");
3403 if (!fun->IsJSFunction()) {
3406 bool caught_exception;
3409 0,
NULL, &caught_exception);
3410 if (caught_exception || !json->IsString()) {
3421 Isolate* isolate = Isolate::Current();
3430 return client_data_;
3434 EventDetailsImpl::EventDetailsImpl(
DebugEvent event,
3435 Handle<JSObject> exec_state,
3436 Handle<JSObject> event_data,
3437 Handle<Object> callback_data,
3440 exec_state_(exec_state),
3441 event_data_(event_data),
3442 callback_data_(callback_data),
3443 client_data_(client_data) {}
3446 DebugEvent EventDetailsImpl::GetEvent()
const {
3462 return GetDebugEventContext(Isolate::Current());
3472 return client_data_;
3476 CommandMessage::CommandMessage() : text_(Vector<
uint16_t>::empty()),
3477 client_data_(
NULL) {
3481 CommandMessage::CommandMessage(
const Vector<uint16_t>& text,
3484 client_data_(data) {
3488 CommandMessage::~CommandMessage() {
3492 void CommandMessage::Dispose() {
3494 delete client_data_;
3495 client_data_ =
NULL;
3499 CommandMessage CommandMessage::New(
const Vector<uint16_t>& command,
3501 return CommandMessage(command.Clone(), data);
3505 CommandMessageQueue::CommandMessageQueue(
int size) : start_(0),
end_(0),
3507 messages_ = NewArray<CommandMessage>(size);
3511 CommandMessageQueue::~CommandMessageQueue() {
3512 while (!IsEmpty()) {
3513 CommandMessage m = Get();
3520 CommandMessage CommandMessageQueue::Get() {
3522 int result = start_;
3523 start_ = (start_ + 1) % size_;
3524 return messages_[result];
3528 void CommandMessageQueue::Put(
const CommandMessage& message) {
3529 if ((
end_ + 1) % size_ == start_) {
3532 messages_[
end_] = message;
3537 void CommandMessageQueue::Expand() {
3538 CommandMessageQueue new_queue(size_ * 2);
3539 while (!IsEmpty()) {
3540 new_queue.Put(Get());
3542 CommandMessage* array_to_free = messages_;
3544 new_queue.messages_ = array_to_free;
3546 new_queue.start_ = new_queue.end_;
3551 LockingCommandMessageQueue::LockingCommandMessageQueue(Logger* logger,
int size)
3552 : logger_(logger), queue_(size) {
3557 LockingCommandMessageQueue::~LockingCommandMessageQueue() {
3562 bool LockingCommandMessageQueue::IsEmpty()
const {
3563 ScopedLock sl(lock_);
3564 return queue_.IsEmpty();
3568 CommandMessage LockingCommandMessageQueue::Get() {
3569 ScopedLock sl(lock_);
3570 CommandMessage result = queue_.Get();
3571 logger_->DebugEvent(
"Get", result.text());
3576 void LockingCommandMessageQueue::Put(
const CommandMessage& message) {
3577 ScopedLock sl(lock_);
3578 queue_.Put(message);
3579 logger_->DebugEvent(
"Put", message.text());
3583 void LockingCommandMessageQueue::Clear() {
3584 ScopedLock sl(lock_);
3589 MessageDispatchHelperThread::MessageDispatchHelperThread(Isolate* isolate)
3590 : Thread(
"v8:MsgDispHelpr"),
3591 sem_(OS::CreateSemaphore(0)), mutex_(OS::CreateMutex()),
3592 already_signalled_(
false) {
3596 MessageDispatchHelperThread::~MessageDispatchHelperThread() {
3602 void MessageDispatchHelperThread::Schedule() {
3604 ScopedLock lock(mutex_);
3605 if (already_signalled_) {
3608 already_signalled_ =
true;
3614 void MessageDispatchHelperThread::Run() {
3618 ScopedLock lock(mutex_);
3619 already_signalled_ =
false;
3623 Isolate::Current()->debugger()->CallMessageDispatchHandler();
3628 #endif // ENABLE_DEBUGGER_SUPPORT
V8EXPORT int Length() const
static Handle< Object > SetProperty(Handle< JSReceiver > object, Handle< String > key, Handle< Object > value, PropertyAttributes attributes, StrictModeFlag strict_mode)
static Object * Cast(Value *obj)
static Object *& Object_at(Address addr)
static Handle< Object > TryCall(Handle< JSFunction > func, Handle< Object > receiver, int argc, Handle< Object > argv[], bool *caught_exception)
Handle< Boolean > V8EXPORT True()
void PrintF(const char *format,...)
Local< Value > Exception() const
static Handle< JSMessageObject > MakeMessageObject(const char *type, MessageLocation *loc, Vector< Handle< Object > > args, Handle< String > stack_trace, Handle< JSArray > stack_frames)
V8EXPORT Local< Value > Get(Handle< Value > key)
static Smi * FromInt(int value)
static int GetIndex(const char *name)
static int ExtractArgcFromMinorKey(int minor_key)
value format" "after each garbage collection") DEFINE_bool(print_cumulative_gc_stat, false, "print cumulative GC statistics in name=value format on exit") DEFINE_bool(trace_gc_verbose, false, "print more details following each garbage collection") DEFINE_bool(trace_fragmentation, false, "report fragmentation for old pointer and data pages") DEFINE_bool(collect_maps, true, "garbage collect maps from which no objects can be reached") DEFINE_bool(flush_code, true, "flush code that we expect not to use again before full gc") DEFINE_bool(incremental_marking, true, "use incremental marking") DEFINE_bool(incremental_marking_steps, true, "do incremental marking steps") DEFINE_bool(trace_incremental_marking, false, "trace progress of the incremental marking") DEFINE_bool(use_idle_notification, true, "Use idle notification to reduce memory footprint.") DEFINE_bool(send_idle_notification, false, "Send idle notifcation between stress runs.") DEFINE_bool(use_ic, true, "use inline caching") DEFINE_bool(native_code_counters, false, "generate extra code for manipulating stats counters") DEFINE_bool(always_compact, false, "Perform compaction on every full GC") DEFINE_bool(lazy_sweeping, true, "Use lazy sweeping for old pointer and data spaces") DEFINE_bool(never_compact, false, "Never perform compaction on full GC-testing only") DEFINE_bool(compact_code_space, true, "Compact code space on full non-incremental collections") DEFINE_bool(cleanup_code_caches_at_gc, true, "Flush inline caches prior to mark compact collection and" "flush code caches in maps during mark compact cycle.") DEFINE_int(random_seed, 0, "Default seed for initializing random generator" "(0, the default, means to use system random).") DEFINE_bool(use_verbose_printer, true, "allows verbose printing") DEFINE_bool(allow_natives_syntax, false, "allow natives syntax") DEFINE_bool(trace_sim, false, "Trace simulator execution") DEFINE_bool(check_icache, false, "Check icache flushes in ARM and MIPS simulator") DEFINE_int(stop_sim_at, 0, "Simulator stop after x number of instructions") DEFINE_int(sim_stack_alignment, 8, "Stack alingment in bytes in simulator(4 or 8, 8 is default)") DEFINE_bool(trace_exception, false, "print stack trace when throwing exceptions") DEFINE_bool(preallocate_message_memory, false, "preallocate some memory to build stack traces.") DEFINE_bool(randomize_hashes, true, "randomize hashes to avoid predictable hash collisions" "(with snapshots this option cannot override the baked-in seed)") DEFINE_int(hash_seed, 0, "Fixed seed to use to hash property keys(0 means random)" "(with snapshots this option cannot override the baked-in seed)") DEFINE_bool(preemption, false, "activate a 100ms timer that switches between V8 threads") DEFINE_bool(regexp_optimization, true, "generate optimized regexp code") DEFINE_bool(testing_bool_flag, true, "testing_bool_flag") DEFINE_int(testing_int_flag, 13, "testing_int_flag") DEFINE_float(testing_float_flag, 2.5, "float-flag") DEFINE_string(testing_string_flag, "Hello, world!", "string-flag") DEFINE_int(testing_prng_seed, 42, "Seed used for threading test randomness") DEFINE_string(testing_serialization_file, "/tmp/serdes", "file in which to serialize heap") DEFINE_bool(help, false, "Print usage message, including flags, on console") DEFINE_bool(dump_counters, false, "Dump counters on exit") DEFINE_string(map_counters, "", "Map counters to a file") DEFINE_args(js_arguments, JSARGUMENTS_INIT, "Pass all remaining arguments to the script.Alias for\"--\".") DEFINE_bool(debug_compile_events, true,"Enable debugger compile events") DEFINE_bool(debug_script_collected_events, true,"Enable debugger script collected events") DEFINE_bool(gdbjit, false,"enable GDBJIT interface (disables compacting GC)") DEFINE_bool(gdbjit_full, false,"enable GDBJIT interface for all code objects") DEFINE_bool(gdbjit_dump, false,"dump elf objects with debug info to disk") DEFINE_string(gdbjit_dump_filter,"","dump only objects containing this substring") DEFINE_bool(force_marking_deque_overflows, false,"force overflows of marking deque by reducing it's size ""to 64 words") DEFINE_bool(stress_compaction, false,"stress the GC compactor to flush out bugs (implies ""--force_marking_deque_overflows)")#define FLAG DEFINE_bool(enable_slow_asserts, false,"enable asserts that are slow to execute") DEFINE_bool(trace_codegen, false,"print name of functions for which code is generated") DEFINE_bool(print_source, false,"pretty print source code") DEFINE_bool(print_builtin_source, false,"pretty print source code for builtins") DEFINE_bool(print_ast, false,"print source AST") DEFINE_bool(print_builtin_ast, false,"print source AST for builtins") DEFINE_string(stop_at,"","function name where to insert a breakpoint") DEFINE_bool(print_builtin_scopes, false,"print scopes for builtins") DEFINE_bool(print_scopes, false,"print scopes") DEFINE_bool(trace_contexts, false,"trace contexts operations") DEFINE_bool(gc_greedy, false,"perform GC prior to some allocations") DEFINE_bool(gc_verbose, false,"print stuff during garbage collection") DEFINE_bool(heap_stats, false,"report heap statistics before and after GC") DEFINE_bool(code_stats, false,"report code statistics after GC") DEFINE_bool(verify_heap, false,"verify heap pointers before and after GC") DEFINE_bool(print_handles, false,"report handles after GC") DEFINE_bool(print_global_handles, false,"report global handles after GC") DEFINE_bool(trace_ic, false,"trace inline cache state transitions") DEFINE_bool(print_interfaces, false,"print interfaces") DEFINE_bool(print_interface_details, false,"print interface inference details") DEFINE_int(print_interface_depth, 5,"depth for printing interfaces") DEFINE_bool(trace_normalization, false,"prints when objects are turned into dictionaries.") DEFINE_bool(trace_lazy, false,"trace lazy compilation") DEFINE_bool(collect_heap_spill_statistics, false,"report heap spill statistics along with heap_stats ""(requires heap_stats)") DEFINE_bool(trace_isolates, false,"trace isolate state changes") DEFINE_bool(log_state_changes, false,"Log state changes.") DEFINE_bool(regexp_possessive_quantifier, false,"enable possessive quantifier syntax for testing") DEFINE_bool(trace_regexp_bytecodes, false,"trace regexp bytecode execution") DEFINE_bool(trace_regexp_assembler, false,"trace regexp macro assembler calls.")#define FLAG DEFINE_bool(log, false,"Minimal logging (no API, code, GC, suspect, or handles samples).") DEFINE_bool(log_all, false,"Log all events to the log file.") DEFINE_bool(log_runtime, false,"Activate runtime system %Log call.") DEFINE_bool(log_api, false,"Log API events to the log file.") DEFINE_bool(log_code, false,"Log code events to the log file without profiling.") DEFINE_bool(log_gc, false,"Log heap samples on garbage collection for the hp2ps tool.") DEFINE_bool(log_handles, false,"Log global handle events.") DEFINE_bool(log_snapshot_positions, false,"log positions of (de)serialized objects in the snapshot.") DEFINE_bool(log_suspect, false,"Log suspect operations.") DEFINE_bool(prof, false,"Log statistical profiling information (implies --log-code).") DEFINE_bool(prof_auto, true,"Used with --prof, starts profiling automatically") DEFINE_bool(prof_lazy, false,"Used with --prof, only does sampling and logging"" when profiler is active (implies --noprof_auto).") DEFINE_bool(prof_browser_mode, true,"Used with --prof, turns on browser-compatible mode for profiling.") DEFINE_bool(log_regexp, false,"Log regular expression execution.") DEFINE_bool(sliding_state_window, false,"Update sliding state window counters.") DEFINE_string(logfile,"v8.log","Specify the name of the log file.") DEFINE_bool(ll_prof, false,"Enable low-level linux profiler.")#define FLAG DEFINE_bool(trace_elements_transitions, false,"trace elements transitions") DEFINE_bool(print_code_stubs, false,"print code stubs") DEFINE_bool(test_secondary_stub_cache, false,"test secondary stub cache by disabling the primary one") DEFINE_bool(test_primary_stub_cache, false,"test primary stub cache by disabling the secondary one") DEFINE_bool(print_code, false,"print generated code") DEFINE_bool(print_opt_code, false,"print optimized code") DEFINE_bool(print_unopt_code, false,"print unoptimized code before ""printing optimized code based on it") DEFINE_bool(print_code_verbose, false,"print more information for code") DEFINE_bool(print_builtin_code, false,"print generated code for builtins")#43"/Users/thlorenz/dev/dx/v8-perf/build/v8/src/flags.cc"2#define FLAG_MODE_DEFINE_DEFAULTS#1"/Users/thlorenz/dev/dx/v8-perf/build/v8/src/flag-definitions.h"1#define FLAG_FULL(ftype, ctype, nam, def, cmt)#define FLAG_READONLY(ftype, ctype, nam, def, cmt)#define DEFINE_implication(whenflag, thenflag)#define DEFINE_bool(nam, def, cmt)#define DEFINE_int(nam, def, cmt)#define DEFINE_float(nam, def, cmt)#define DEFINE_string(nam, def, cmt)#define DEFINE_args(nam, def, cmt)#define FLAG DEFINE_bool(use_strict, false,"enforce strict mode") DEFINE_bool(es5_readonly, false,"activate correct semantics for inheriting readonliness") DEFINE_bool(es52_globals, false,"activate new semantics for global var declarations") DEFINE_bool(harmony_typeof, false,"enable harmony semantics for typeof") DEFINE_bool(harmony_scoping, false,"enable harmony block scoping") DEFINE_bool(harmony_modules, false,"enable harmony modules (implies block scoping)") DEFINE_bool(harmony_proxies, false,"enable harmony proxies") DEFINE_bool(harmony_collections, false,"enable harmony collections (sets, maps, and weak maps)") DEFINE_bool(harmony, false,"enable all harmony features (except typeof)") DEFINE_implication(harmony, harmony_scoping) DEFINE_implication(harmony, harmony_modules) DEFINE_implication(harmony, harmony_proxies) DEFINE_implication(harmony, harmony_collections) DEFINE_implication(harmony_modules, harmony_scoping) DEFINE_bool(packed_arrays, false,"optimizes arrays that have no holes") DEFINE_bool(smi_only_arrays, true,"tracks arrays with only smi values") DEFINE_bool(clever_optimizations, true,"Optimize object size, Array shift, DOM strings and string +") DEFINE_bool(unbox_double_arrays, true,"automatically unbox arrays of doubles") DEFINE_bool(string_slices, true,"use string slices") DEFINE_bool(crankshaft, true,"use crankshaft") DEFINE_string(hydrogen_filter,"","optimization filter") DEFINE_bool(use_range, true,"use hydrogen range analysis") DEFINE_bool(eliminate_dead_phis, true,"eliminate dead phis") DEFINE_bool(use_gvn, true,"use hydrogen global value numbering") DEFINE_bool(use_canonicalizing, true,"use hydrogen instruction canonicalizing") DEFINE_bool(use_inlining, true,"use function inlining") DEFINE_int(max_inlined_source_size, 600,"maximum source size in bytes considered for a single inlining") DEFINE_int(max_inlined_nodes, 196,"maximum number of AST nodes considered for a single inlining") DEFINE_int(max_inlined_nodes_cumulative, 196,"maximum cumulative number of AST nodes considered for inlining") DEFINE_bool(loop_invariant_code_motion, true,"loop invariant code motion") DEFINE_bool(collect_megamorphic_maps_from_stub_cache, true,"crankshaft harvests type feedback from stub cache") DEFINE_bool(hydrogen_stats, false,"print statistics for hydrogen") DEFINE_bool(trace_hydrogen, false,"trace generated hydrogen to file") DEFINE_string(trace_phase,"Z","trace generated IR for specified phases") DEFINE_bool(trace_inlining, false,"trace inlining decisions") DEFINE_bool(trace_alloc, false,"trace register allocator") DEFINE_bool(trace_all_uses, false,"trace all use positions") DEFINE_bool(trace_range, false,"trace range analysis") DEFINE_bool(trace_gvn, false,"trace global value numbering") DEFINE_bool(trace_representation, false,"trace representation types") DEFINE_bool(stress_pointer_maps, false,"pointer map for every instruction") DEFINE_bool(stress_environments, false,"environment for every instruction") DEFINE_int(deopt_every_n_times, 0,"deoptimize every n times a deopt point is passed") DEFINE_bool(trap_on_deopt, false,"put a break point before deoptimizing") DEFINE_bool(deoptimize_uncommon_cases, true,"deoptimize uncommon cases") DEFINE_bool(polymorphic_inlining, true,"polymorphic inlining") DEFINE_bool(use_osr, true,"use on-stack replacement") DEFINE_bool(array_bounds_checks_elimination, false,"perform array bounds checks elimination") DEFINE_bool(array_index_dehoisting, false,"perform array index dehoisting") DEFINE_bool(trace_osr, false,"trace on-stack replacement") DEFINE_int(stress_runs, 0,"number of stress runs") DEFINE_bool(optimize_closures, true,"optimize closures") DEFINE_bool(inline_construct, true,"inline constructor calls") DEFINE_bool(inline_arguments, true,"inline functions with arguments object") DEFINE_int(loop_weight, 1,"loop weight for representation inference") DEFINE_bool(optimize_for_in, true,"optimize functions containing for-in loops") DEFINE_bool(experimental_profiler, true,"enable all profiler experiments") DEFINE_bool(watch_ic_patching, false,"profiler considers IC stability") DEFINE_int(frame_count, 1,"number of stack frames inspected by the profiler") DEFINE_bool(self_optimization, false,"primitive functions trigger their own optimization") DEFINE_bool(direct_self_opt, false,"call recompile stub directly when self-optimizing") DEFINE_bool(retry_self_opt, false,"re-try self-optimization if it failed") DEFINE_bool(count_based_interrupts, false,"trigger profiler ticks based on counting instead of timing") DEFINE_bool(interrupt_at_exit, false,"insert an interrupt check at function exit") DEFINE_bool(weighted_back_edges, false,"weight back edges by jump distance for interrupt triggering") DEFINE_int(interrupt_budget, 5900,"execution budget before interrupt is triggered") DEFINE_int(type_info_threshold, 15,"percentage of ICs that must have type info to allow optimization") DEFINE_int(self_opt_count, 130,"call count before self-optimization") DEFINE_implication(experimental_profiler, watch_ic_patching) DEFINE_implication(experimental_profiler, self_optimization) DEFINE_implication(experimental_profiler, retry_self_opt) DEFINE_implication(experimental_profiler, count_based_interrupts) DEFINE_implication(experimental_profiler, interrupt_at_exit) DEFINE_implication(experimental_profiler, weighted_back_edges) DEFINE_bool(trace_opt_verbose, false,"extra verbose compilation tracing") DEFINE_implication(trace_opt_verbose, trace_opt) DEFINE_bool(debug_code, false,"generate extra code (assertions) for debugging") DEFINE_bool(code_comments, false,"emit comments in code disassembly") DEFINE_bool(enable_sse2, true,"enable use of SSE2 instructions if available") DEFINE_bool(enable_sse3, true,"enable use of SSE3 instructions if available") DEFINE_bool(enable_sse4_1, true,"enable use of SSE4.1 instructions if available") DEFINE_bool(enable_cmov, true,"enable use of CMOV instruction if available") DEFINE_bool(enable_rdtsc, true,"enable use of RDTSC instruction if available") DEFINE_bool(enable_sahf, true,"enable use of SAHF instruction if available (X64 only)") DEFINE_bool(enable_vfp3, true,"enable use of VFP3 instructions if available - this implies ""enabling ARMv7 instructions (ARM only)") DEFINE_bool(enable_armv7, true,"enable use of ARMv7 instructions if available (ARM only)") DEFINE_bool(enable_fpu, true,"enable use of MIPS FPU instructions if available (MIPS only)") DEFINE_string(expose_natives_as, NULL,"expose natives in global object") DEFINE_string(expose_debug_as, NULL,"expose debug in global object") DEFINE_bool(expose_gc, false,"expose gc extension") DEFINE_bool(expose_externalize_string, false,"expose externalize string extension") DEFINE_int(stack_trace_limit, 10,"number of stack frames to capture") DEFINE_bool(builtins_in_stack_traces, false,"show built-in functions in stack traces") DEFINE_bool(disable_native_files, false,"disable builtin natives files") DEFINE_bool(inline_new, true,"use fast inline allocation") DEFINE_bool(stack_trace_on_abort, true,"print a stack trace if an assertion failure occurs") DEFINE_bool(trace, false,"trace function calls") DEFINE_bool(mask_constants_with_cookie, true,"use random jit cookie to mask large constants") DEFINE_bool(lazy, true,"use lazy compilation") DEFINE_bool(trace_opt, false,"trace lazy optimization") DEFINE_bool(trace_opt_stats, false,"trace lazy optimization statistics") DEFINE_bool(opt, true,"use adaptive optimizations") DEFINE_bool(always_opt, false,"always try to optimize functions") DEFINE_bool(prepare_always_opt, false,"prepare for turning on always opt") DEFINE_bool(trace_deopt, false,"trace deoptimization") DEFINE_int(min_preparse_length, 1024,"minimum length for automatic enable preparsing") DEFINE_bool(always_full_compiler, false,"try to use the dedicated run-once backend for all code") DEFINE_bool(trace_bailout, false,"print reasons for falling back to using the classic V8 backend") DEFINE_bool(compilation_cache, true,"enable compilation cache") DEFINE_bool(cache_prototype_transitions, true,"cache prototype transitions") DEFINE_bool(trace_debug_json, false,"trace debugging JSON request/response") DEFINE_bool(debugger_auto_break, true,"automatically set the debug break flag when debugger commands are ""in the queue") DEFINE_bool(enable_liveedit, true,"enable liveedit experimental feature") DEFINE_bool(break_on_abort, true,"always cause a debug break before aborting") DEFINE_int(stack_size, kPointerSize *123,"default size of stack region v8 is allowed to use (in kBytes)") DEFINE_int(max_stack_trace_source_length, 300,"maximum length of function source code printed in a stack trace.") DEFINE_bool(always_inline_smi_code, false,"always inline smi code in non-opt code") DEFINE_int(max_new_space_size, 0,"max size of the new generation (in kBytes)") DEFINE_int(max_old_space_size, 0,"max size of the old generation (in Mbytes)") DEFINE_int(max_executable_size, 0,"max size of executable memory (in Mbytes)") DEFINE_bool(gc_global, false,"always perform global GCs") DEFINE_int(gc_interval,-1,"garbage collect after <n> allocations") DEFINE_bool(trace_gc, false,"print one trace line following each garbage collection") DEFINE_bool(trace_gc_nvp, false,"print one detailed trace line in name=value format ""after each garbage collection") DEFINE_bool(print_cumulative_gc_stat, false,"print cumulative GC statistics in name=value format on exit") DEFINE_bool(trace_gc_verbose, false,"print more details following each garbage collection") DEFINE_bool(trace_fragmentation, false,"report fragmentation for old pointer and data pages") DEFINE_bool(collect_maps, true,"garbage collect maps from which no objects can be reached") DEFINE_bool(flush_code, true,"flush code that we expect not to use again before full gc") DEFINE_bool(incremental_marking, true,"use incremental marking") DEFINE_bool(incremental_marking_steps, true,"do incremental marking steps") DEFINE_bool(trace_incremental_marking, false,"trace progress of the incremental marking") DEFINE_bool(use_idle_notification, true,"Use idle notification to reduce memory footprint.") DEFINE_bool(send_idle_notification, false,"Send idle notifcation between stress runs.") DEFINE_bool(use_ic, true,"use inline caching") DEFINE_bool(native_code_counters, false,"generate extra code for manipulating stats counters") DEFINE_bool(always_compact, false,"Perform compaction on every full GC") DEFINE_bool(lazy_sweeping, true,"Use lazy sweeping for old pointer and data spaces") DEFINE_bool(never_compact, false,"Never perform compaction on full GC - testing only") DEFINE_bool(compact_code_space, true,"Compact code space on full non-incremental collections") DEFINE_bool(cleanup_code_caches_at_gc, true,"Flush inline caches prior to mark compact collection and ""flush code caches in maps during mark compact cycle.") DEFINE_int(random_seed, 0,"Default seed for initializing random generator ""(0, the default, means to use system random).") DEFINE_bool(use_verbose_printer, true,"allows verbose printing") DEFINE_bool(allow_natives_syntax, false,"allow natives syntax") DEFINE_bool(trace_sim, false,"Trace simulator execution") DEFINE_bool(check_icache, false,"Check icache flushes in ARM and MIPS simulator") DEFINE_int(stop_sim_at, 0,"Simulator stop after x number of instructions") DEFINE_int(sim_stack_alignment, 8,"Stack alingment in bytes in simulator (4 or 8, 8 is default)") DEFINE_bool(trace_exception, false,"print stack trace when throwing exceptions") DEFINE_bool(preallocate_message_memory, false,"preallocate some memory to build stack traces.") DEFINE_bool(randomize_hashes, true,"randomize hashes to avoid predictable hash collisions ""(with snapshots this option cannot override the baked-in seed)") DEFINE_int(hash_seed, 0,"Fixed seed to use to hash property keys (0 means random)""(with snapshots this option cannot override the baked-in seed)") DEFINE_bool(preemption, false,"activate a 100ms timer that switches between V8 threads") DEFINE_bool(regexp_optimization, true,"generate optimized regexp code") DEFINE_bool(testing_bool_flag, true,"testing_bool_flag") DEFINE_int(testing_int_flag, 13,"testing_int_flag") DEFINE_float(testing_float_flag, 2.5,"float-flag") DEFINE_string(testing_string_flag,"Hello, world!","string-flag") DEFINE_int(testing_prng_seed, 42,"Seed used for threading test randomness") DEFINE_string(testing_serialization_file,"/tmp/serdes","file in which to serialize heap") DEFINE_bool(help, false,"Print usage message, including flags, on console") DEFINE_bool(dump_counters, false,"Dump counters on exit") DEFINE_string(map_counters,"","Map counters to a file") DEFINE_args(js_arguments, JSARGUMENTS_INIT,"Pass all remaining arguments to the script. Alias for \"--\".") DEFINE_bool(debug_compile_events, true,"Enable debugger compile events") DEFINE_bool(debug_script_collected_events, true,"Enable debugger script collected events") DEFINE_bool(gdbjit, false,"enable GDBJIT interface (disables compacting GC)") DEFINE_bool(gdbjit_full, false,"enable GDBJIT interface for all code objects") DEFINE_bool(gdbjit_dump, false,"dump elf objects with debug info to disk") DEFINE_string(gdbjit_dump_filter,"","dump only objects containing this substring") DEFINE_bool(force_marking_deque_overflows, false,"force overflows of marking deque by reducing it's size ""to 64 words") DEFINE_bool(stress_compaction, false,"stress the GC compactor to flush out bugs (implies ""--force_marking_deque_overflows)")#define FLAG DEFINE_bool(enable_slow_asserts, false,"enable asserts that are slow to execute") DEFINE_bool(trace_codegen, false,"print name of functions for which code is generated") DEFINE_bool(print_source, false,"pretty print source code") DEFINE_bool(print_builtin_source, false,"pretty print source code for builtins") DEFINE_bool(print_ast, false,"print source AST") DEFINE_bool(print_builtin_ast, false,"print source AST for builtins") DEFINE_string(stop_at,"","function name where to insert a breakpoint") DEFINE_bool(print_builtin_scopes, false,"print scopes for builtins") DEFINE_bool(print_scopes, false,"print scopes") DEFINE_bool(trace_contexts, false,"trace contexts operations") DEFINE_bool(gc_greedy, false,"perform GC prior to some allocations") DEFINE_bool(gc_verbose, false,"print stuff during garbage collection") DEFINE_bool(heap_stats, false,"report heap statistics before and after GC") DEFINE_bool(code_stats, false,"report code statistics after GC") DEFINE_bool(verify_heap, false,"verify heap pointers before and after GC") DEFINE_bool(print_handles, false,"report handles after GC") DEFINE_bool(print_global_handles, false,"report global handles after GC") DEFINE_bool(trace_ic, false,"trace inline cache state transitions") DEFINE_bool(print_interfaces, false,"print interfaces") DEFINE_bool(print_interface_details, false,"print interface inference details") DEFINE_int(print_interface_depth, 5,"depth for printing interfaces") DEFINE_bool(trace_normalization, false,"prints when objects are turned into dictionaries.") DEFINE_bool(trace_lazy, false,"trace lazy compilation") DEFINE_bool(collect_heap_spill_statistics, false,"report heap spill statistics along with heap_stats ""(requires heap_stats)") DEFINE_bool(trace_isolates, false,"trace isolate state changes") DEFINE_bool(log_state_changes, false,"Log state changes.") DEFINE_bool(regexp_possessive_quantifier, false,"enable possessive quantifier syntax for testing") DEFINE_bool(trace_regexp_bytecodes, false,"trace regexp bytecode execution") DEFINE_bool(trace_regexp_assembler, false,"trace regexp macro assembler calls.")#define FLAG DEFINE_bool(log, false,"Minimal logging (no API, code, GC, suspect, or handles samples).") DEFINE_bool(log_all, false,"Log all events to the log file.") DEFINE_bool(log_runtime, false,"Activate runtime system %Log call.") DEFINE_bool(log_api, false,"Log API events to the log file.") DEFINE_bool(log_code, false,"Log code events to the log file without profiling.") DEFINE_bool(log_gc, false,"Log heap samples on garbage collection for the hp2ps tool.") DEFINE_bool(log_handles, false,"Log global handle events.") DEFINE_bool(log_snapshot_positions, false,"log positions of (de)serialized objects in the snapshot.") DEFINE_bool(log_suspect, false,"Log suspect operations.") DEFINE_bool(prof, false,"Log statistical profiling information (implies --log-code).") DEFINE_bool(prof_auto, true,"Used with --prof, starts profiling automatically") DEFINE_bool(prof_lazy, false,"Used with --prof, only does sampling and logging"" when profiler is active (implies --noprof_auto).") DEFINE_bool(prof_browser_mode, true,"Used with --prof, turns on browser-compatible mode for profiling.") DEFINE_bool(log_regexp, false,"Log regular expression execution.") DEFINE_bool(sliding_state_window, false,"Update sliding state window counters.") DEFINE_string(logfile,"v8.log","Specify the name of the log file.") DEFINE_bool(ll_prof, false,"Enable low-level linux profiler.")#define FLAG DEFINE_bool(trace_elements_transitions, false,"trace elements transitions") DEFINE_bool(print_code_stubs, false,"print code stubs") DEFINE_bool(test_secondary_stub_cache, false,"test secondary stub cache by disabling the primary one") DEFINE_bool(test_primary_stub_cache, false,"test primary stub cache by disabling the secondary one") DEFINE_bool(print_code, false,"print generated code") DEFINE_bool(print_opt_code, false,"print optimized code") DEFINE_bool(print_unopt_code, false,"print unoptimized code before ""printing optimized code based on it") DEFINE_bool(print_code_verbose, false,"print more information for code") DEFINE_bool(print_builtin_code, false,"print generated code for builtins")#47"/Users/thlorenz/dev/dx/v8-perf/build/v8/src/flags.cc"2 namespace{struct Flag{enum FlagType{TYPE_BOOL, TYPE_INT, TYPE_FLOAT, TYPE_STRING, TYPE_ARGS} name
static Handle< T > cast(Handle< S > that)
static Vector< const char > GetScriptName(int index)
static V8EXPORT Local< String > New(const char *data, int length=-1)
void(* DebugMessageDispatchHandler)()
V8EXPORT Local< Value > Call(Handle< Object > recv, int argc, Handle< Value > argv[])
#define ASSERT(condition)
static const int kPatchReturnSequenceAddressOffset
static Script * cast(Object *obj)
void(* MessageHandler2)(const Message &message)
static void DeoptimizeAll()
V8EXPORT Local< String > ToString() const
Handle< Object > GetProperty(Handle< JSReceiver > obj, const char *name)
static Function * Cast(Value *obj)
#define RETURN_IF_EMPTY_HANDLE_VALUE(isolate, call, value)
static Smi * cast(Object *object)
HANDLE HANDLE LPSTACKFRAME64 StackFrame
static const int kNoGCFlags
Handle< JSValue > GetScriptWrapper(Handle< Script > script)
Entry * Lookup(void *key, uint32_t hash, bool insert, FreeStoreAllocationPolicyallocator=FreeStoreAllocationPolicy())
static Mutex * CreateMutex()
static Code * GetCodeFromTargetAddress(Address address)
static const int kMakeHeapIterableMask
static String * Cast(v8::Value *obj)
static const int kCallTargetAddressOffset
Handle< Boolean > V8EXPORT False()
static Handle< Object > Call(Handle< Object > callable, Handle< Object > receiver, int argc, Handle< Object > argv[], bool *pending_exception, bool convert_receiver=false)
Vector< const char > CStrVector(const char *data)
static const int kDebugBreakSlotLength
static Local< Context > ToLocal(v8::internal::Handle< v8::internal::Context > obj)
void(* EventCallback2)(const EventDetails &event_details)
static Address target_address_at(Address pc)
void(* HostDispatchHandler)()
JavaScriptFrameIteratorTemp< StackFrameIterator > JavaScriptFrameIterator
static const int kContextOffset
static const int kFunctionOffset
Object * JSCallerSavedBuffer[kNumJSCallerSaved]
static Handle< SharedFunctionInfo > Compile(Handle< String > source, Handle< Object > script_name, int line_offset, int column_offset, v8::Extension *extension, ScriptDataImpl *pre_data, Handle< Object > script_data, NativesFlag is_natives_code)
v8::Handle< v8::Value > Load(const v8::Arguments &args)
static Handle< String > null()
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination trace on stack replacement optimize closures functions with arguments object optimize functions containing for in loops profiler considers IC stability primitive functions trigger their own optimization re try self optimization if it failed insert an interrupt check at function exit execution budget before interrupt is triggered call count before self optimization self_optimization count_based_interrupts weighted_back_edges trace_opt emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 enable use of ARMv7 instructions if enable use of MIPS FPU instructions if NULL
static bool EnsureCompiled(Handle< SharedFunctionInfo > shared, ClearExceptionFlag flag)
Local< T > Close(Handle< T > value)
static FixedArray * cast(Object *obj)
V8EXPORT int WriteAscii(char *buffer, int start=0, int length=-1, int options=NO_OPTIONS) const
static bool CompileLazy(CompilationInfo *info)
static const int kBoundFunctionIndex
static const int kMaxInliningLevels
V8EXPORT Local< Boolean > ToBoolean() const
static const int kCodeOffset
static void DebugBreak(Isolate *isolate=NULL)
static void ReportMessage(Isolate *isolate, MessageLocation *loc, Handle< Object > message)
static const int kMarkerOffset
void DeleteArray(T *array)
static const int kPatchDebugBreakSlotAddressOffset
static void FatalProcessOutOfMemory(const char *location, bool take_snapshot=false)
static v8::internal::Handle< v8::internal::TemplateInfo > OpenHandle(const Template *that)
static JSFunction * cast(Object *obj)