target_code(Code::GetCodeFromTargetAddress(target)); if (target_code->kind() == Code::STUB) { return target_code->major_key() == CodeStub::CallFunction; } return target_code->is_call_stub(); } return false; } void BreakLocationIterator::PrepareStepIn(Isolate* isolate) { #ifdef DEBUG HandleScope scope(isolate); // Step in can only be prepared if currently positioned on an IC call, // construct call or CallFunction stub call. Address target = rinfo()->target_address(); Handle target_code(Code::GetCodeFromTargetAddress(target)); // All the following stuff is needed only for assertion checks so the code // is wrapped in ifdef. Handle maybe_call_function_stub = target_code; if (IsDebugBreak()) { Address original_target = original_rinfo()->target_address(); maybe_call_function_stub = Handle(Code::GetCodeFromTargetAddress(original_target)); } bool is_call_function_stub = (maybe_call_function_stub->kind() == Code::STUB && maybe_call_function_stub->major_key() == CodeStub::CallFunction); // Step in through construct call requires no changes to the running code. // Step in through getters/setters should already be prepared as well // because caller of this function (Debug::PrepareStep) is expected to // flood the top frame's function with one shot breakpoints. // Step in through CallFunction stub should also be prepared by caller of // this function (Debug::PrepareStep) which should flood target function // with breakpoints. ASSERT(RelocInfo::IsConstructCall(rmode()) || target_code->is_inline_cache_stub() || is_call_function_stub); #endif } // Check whether the break point is at a position which will exit the function. bool BreakLocationIterator::IsExit() const { return (RelocInfo::IsJSReturn(rmode())); } bool BreakLocationIterator::HasBreakPoint() { return debug_info_->HasBreakPoint(code_position()); } // Check whether there is a debug break at the current position. bool BreakLocationIterator::IsDebugBreak() { if (RelocInfo::IsJSReturn(rmode())) { return IsDebugBreakAtReturn(); } else if (IsDebugBreakSlot()) { return IsDebugBreakAtSlot(); } else { return Debug::IsDebugBreak(rinfo()->target_address()); } } // Find the builtin to use for invoking the debug break static Handle DebugBreakForIC(Handle code, RelocInfo::Mode mode) { Isolate* isolate = code->GetIsolate(); // Find the builtin debug break function matching the calling convention // used by the call site. if (code->is_inline_cache_stub()) { switch (code->kind()) { case Code::CALL_IC: return isolate->builtins()->CallICStub_DebugBreak(); case Code::LOAD_IC: return isolate->builtins()->LoadIC_DebugBreak(); case Code::STORE_IC: return isolate->builtins()->StoreIC_DebugBreak(); case Code::KEYED_LOAD_IC: return isolate->builtins()->KeyedLoadIC_DebugBreak(); case Code::KEYED_STORE_IC: return isolate->builtins()->KeyedStoreIC_DebugBreak(); case Code::COMPARE_NIL_IC: return isolate->builtins()->CompareNilIC_DebugBreak(); default: UNREACHABLE(); } } if (RelocInfo::IsConstructCall(mode)) { if (code->has_function_cache()) { return isolate->builtins()->CallConstructStub_Recording_DebugBreak(); } else { return isolate->builtins()->CallConstructStub_DebugBreak(); } } if (code->kind() == Code::STUB) { ASSERT(code->major_key() == CodeStub::CallFunction); return isolate->builtins()->CallFunctionStub_DebugBreak(); } UNREACHABLE(); return Handle::null(); } void BreakLocationIterator::SetDebugBreakAtIC() { // Patch the original code with the current address as the current address // might have changed by the inline caching since the code was copied. original_rinfo()->set_target_address(rinfo()->target_address()); RelocInfo::Mode mode = rmode(); if (RelocInfo::IsCodeTarget(mode)) { Address target = rinfo()->target_address(); Handle target_code(Code::GetCodeFromTargetAddress(target)); // Patch the code to invoke the builtin debug break function matching the // calling convention used by the call site. Handle dbgbrk_code = DebugBreakForIC(target_code, mode); rinfo()->set_target_address(dbgbrk_code->entry()); } } void BreakLocationIterator::ClearDebugBreakAtIC() { // Patch the code to the original invoke. rinfo()->set_target_address(original_rinfo()->target_address()); } bool BreakLocationIterator::IsDebuggerStatement() { return RelocInfo::DEBUG_BREAK == rmode(); } bool BreakLocationIterator::IsDebugBreakSlot() { return RelocInfo::DEBUG_BREAK_SLOT == rmode(); } Object* BreakLocationIterator::BreakPointObjects() { return debug_info_->GetBreakPointObjects(code_position()); } // Clear out all the debug break code. This is ONLY supposed to be used when // shutting down the debugger as it will leave the break point information in // DebugInfo even though the code is patched back to the non break point state. void BreakLocationIterator::ClearAllDebugBreak() { while (!Done()) { ClearDebugBreak(); Next(); } } bool BreakLocationIterator::RinfoDone() const { ASSERT(reloc_iterator_->done() == reloc_iterator_original_->done()); return reloc_iterator_->done(); } void BreakLocationIterator::RinfoNext() { reloc_iterator_->next(); reloc_iterator_original_->next(); #ifdef DEBUG ASSERT(reloc_iterator_->done() == reloc_iterator_original_->done()); if (!reloc_iterator_->done()) { ASSERT(rmode() == original_rmode()); } #endif } // Threading support. void Debug::ThreadInit() { thread_local_.break_count_ = 0; thread_local_.break_id_ = 0; thread_local_.break_frame_id_ = StackFrame::NO_ID; thread_local_.last_step_action_ = StepNone; thread_local_.last_statement_position_ = RelocInfo::kNoPosition; thread_local_.step_count_ = 0; thread_local_.last_fp_ = 0; thread_local_.queued_step_count_ = 0; thread_local_.step_into_fp_ = 0; thread_local_.step_out_fp_ = 0; // TODO(isolates): frames_are_dropped_? thread_local_.current_debug_scope_ = NULL; thread_local_.restarter_frame_function_pointer_ = NULL; thread_local_.promise_on_stack_ = NULL; } char* Debug::ArchiveDebug(char* storage) { char* to = storage; MemCopy(to, reinterpret_cast(&thread_local_), sizeof(ThreadLocal)); ThreadInit(); return storage + ArchiveSpacePerThread(); } char* Debug::RestoreDebug(char* storage) { char* from = storage; MemCopy(reinterpret_cast(&thread_local_), from, sizeof(ThreadLocal)); return storage + ArchiveSpacePerThread(); } int Debug::ArchiveSpacePerThread() { return sizeof(ThreadLocal); } ScriptCache::ScriptCache(Isolate* isolate) : HashMap(HashMap::PointersMatch), isolate_(isolate), collected_scripts_(10) { Heap* heap = isolate_->heap(); HandleScope scope(isolate_); // Perform two GCs to get rid of all unreferenced scripts. The first GC gets // rid of all the cached script wrappers and the second gets rid of the // scripts which are no longer referenced. heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "ScriptCache"); heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "ScriptCache"); // Scan heap for Script objects. HeapIterator iterator(heap); DisallowHeapAllocation no_allocation; for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { if (obj->IsScript() && Script::cast(obj)->HasValidSource()) { Add(Handle 登录后可以享受更多权益 您还没有登录,登录后您可以: 收藏Android系统代码 收藏喜欢的文章 多个平台共享账号 去登录 首次使用?从这里 注册
target_code(Code::GetCodeFromTargetAddress(target)); // All the following stuff is needed only for assertion checks so the code // is wrapped in ifdef. Handle maybe_call_function_stub = target_code; if (IsDebugBreak()) { Address original_target = original_rinfo()->target_address(); maybe_call_function_stub = Handle(Code::GetCodeFromTargetAddress(original_target)); } bool is_call_function_stub = (maybe_call_function_stub->kind() == Code::STUB && maybe_call_function_stub->major_key() == CodeStub::CallFunction); // Step in through construct call requires no changes to the running code. // Step in through getters/setters should already be prepared as well // because caller of this function (Debug::PrepareStep) is expected to // flood the top frame's function with one shot breakpoints. // Step in through CallFunction stub should also be prepared by caller of // this function (Debug::PrepareStep) which should flood target function // with breakpoints. ASSERT(RelocInfo::IsConstructCall(rmode()) || target_code->is_inline_cache_stub() || is_call_function_stub); #endif } // Check whether the break point is at a position which will exit the function. bool BreakLocationIterator::IsExit() const { return (RelocInfo::IsJSReturn(rmode())); } bool BreakLocationIterator::HasBreakPoint() { return debug_info_->HasBreakPoint(code_position()); } // Check whether there is a debug break at the current position. bool BreakLocationIterator::IsDebugBreak() { if (RelocInfo::IsJSReturn(rmode())) { return IsDebugBreakAtReturn(); } else if (IsDebugBreakSlot()) { return IsDebugBreakAtSlot(); } else { return Debug::IsDebugBreak(rinfo()->target_address()); } } // Find the builtin to use for invoking the debug break static Handle DebugBreakForIC(Handle code, RelocInfo::Mode mode) { Isolate* isolate = code->GetIsolate(); // Find the builtin debug break function matching the calling convention // used by the call site. if (code->is_inline_cache_stub()) { switch (code->kind()) { case Code::CALL_IC: return isolate->builtins()->CallICStub_DebugBreak(); case Code::LOAD_IC: return isolate->builtins()->LoadIC_DebugBreak(); case Code::STORE_IC: return isolate->builtins()->StoreIC_DebugBreak(); case Code::KEYED_LOAD_IC: return isolate->builtins()->KeyedLoadIC_DebugBreak(); case Code::KEYED_STORE_IC: return isolate->builtins()->KeyedStoreIC_DebugBreak(); case Code::COMPARE_NIL_IC: return isolate->builtins()->CompareNilIC_DebugBreak(); default: UNREACHABLE(); } } if (RelocInfo::IsConstructCall(mode)) { if (code->has_function_cache()) { return isolate->builtins()->CallConstructStub_Recording_DebugBreak(); } else { return isolate->builtins()->CallConstructStub_DebugBreak(); } } if (code->kind() == Code::STUB) { ASSERT(code->major_key() == CodeStub::CallFunction); return isolate->builtins()->CallFunctionStub_DebugBreak(); } UNREACHABLE(); return Handle::null(); } void BreakLocationIterator::SetDebugBreakAtIC() { // Patch the original code with the current address as the current address // might have changed by the inline caching since the code was copied. original_rinfo()->set_target_address(rinfo()->target_address()); RelocInfo::Mode mode = rmode(); if (RelocInfo::IsCodeTarget(mode)) { Address target = rinfo()->target_address(); Handle target_code(Code::GetCodeFromTargetAddress(target)); // Patch the code to invoke the builtin debug break function matching the // calling convention used by the call site. Handle dbgbrk_code = DebugBreakForIC(target_code, mode); rinfo()->set_target_address(dbgbrk_code->entry()); } } void BreakLocationIterator::ClearDebugBreakAtIC() { // Patch the code to the original invoke. rinfo()->set_target_address(original_rinfo()->target_address()); } bool BreakLocationIterator::IsDebuggerStatement() { return RelocInfo::DEBUG_BREAK == rmode(); } bool BreakLocationIterator::IsDebugBreakSlot() { return RelocInfo::DEBUG_BREAK_SLOT == rmode(); } Object* BreakLocationIterator::BreakPointObjects() { return debug_info_->GetBreakPointObjects(code_position()); } // Clear out all the debug break code. This is ONLY supposed to be used when // shutting down the debugger as it will leave the break point information in // DebugInfo even though the code is patched back to the non break point state. void BreakLocationIterator::ClearAllDebugBreak() { while (!Done()) { ClearDebugBreak(); Next(); } } bool BreakLocationIterator::RinfoDone() const { ASSERT(reloc_iterator_->done() == reloc_iterator_original_->done()); return reloc_iterator_->done(); } void BreakLocationIterator::RinfoNext() { reloc_iterator_->next(); reloc_iterator_original_->next(); #ifdef DEBUG ASSERT(reloc_iterator_->done() == reloc_iterator_original_->done()); if (!reloc_iterator_->done()) { ASSERT(rmode() == original_rmode()); } #endif } // Threading support. void Debug::ThreadInit() { thread_local_.break_count_ = 0; thread_local_.break_id_ = 0; thread_local_.break_frame_id_ = StackFrame::NO_ID; thread_local_.last_step_action_ = StepNone; thread_local_.last_statement_position_ = RelocInfo::kNoPosition; thread_local_.step_count_ = 0; thread_local_.last_fp_ = 0; thread_local_.queued_step_count_ = 0; thread_local_.step_into_fp_ = 0; thread_local_.step_out_fp_ = 0; // TODO(isolates): frames_are_dropped_? thread_local_.current_debug_scope_ = NULL; thread_local_.restarter_frame_function_pointer_ = NULL; thread_local_.promise_on_stack_ = NULL; } char* Debug::ArchiveDebug(char* storage) { char* to = storage; MemCopy(to, reinterpret_cast(&thread_local_), sizeof(ThreadLocal)); ThreadInit(); return storage + ArchiveSpacePerThread(); } char* Debug::RestoreDebug(char* storage) { char* from = storage; MemCopy(reinterpret_cast(&thread_local_), from, sizeof(ThreadLocal)); return storage + ArchiveSpacePerThread(); } int Debug::ArchiveSpacePerThread() { return sizeof(ThreadLocal); } ScriptCache::ScriptCache(Isolate* isolate) : HashMap(HashMap::PointersMatch), isolate_(isolate), collected_scripts_(10) { Heap* heap = isolate_->heap(); HandleScope scope(isolate_); // Perform two GCs to get rid of all unreferenced scripts. The first GC gets // rid of all the cached script wrappers and the second gets rid of the // scripts which are no longer referenced. heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "ScriptCache"); heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "ScriptCache"); // Scan heap for Script objects. HeapIterator iterator(heap); DisallowHeapAllocation no_allocation; for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { if (obj->IsScript() && Script::cast(obj)->HasValidSource()) { Add(Handle 登录后可以享受更多权益 您还没有登录,登录后您可以: 收藏Android系统代码 收藏喜欢的文章 多个平台共享账号 去登录 首次使用?从这里 注册
maybe_call_function_stub = target_code; if (IsDebugBreak()) { Address original_target = original_rinfo()->target_address(); maybe_call_function_stub = Handle(Code::GetCodeFromTargetAddress(original_target)); } bool is_call_function_stub = (maybe_call_function_stub->kind() == Code::STUB && maybe_call_function_stub->major_key() == CodeStub::CallFunction); // Step in through construct call requires no changes to the running code. // Step in through getters/setters should already be prepared as well // because caller of this function (Debug::PrepareStep) is expected to // flood the top frame's function with one shot breakpoints. // Step in through CallFunction stub should also be prepared by caller of // this function (Debug::PrepareStep) which should flood target function // with breakpoints. ASSERT(RelocInfo::IsConstructCall(rmode()) || target_code->is_inline_cache_stub() || is_call_function_stub); #endif } // Check whether the break point is at a position which will exit the function. bool BreakLocationIterator::IsExit() const { return (RelocInfo::IsJSReturn(rmode())); } bool BreakLocationIterator::HasBreakPoint() { return debug_info_->HasBreakPoint(code_position()); } // Check whether there is a debug break at the current position. bool BreakLocationIterator::IsDebugBreak() { if (RelocInfo::IsJSReturn(rmode())) { return IsDebugBreakAtReturn(); } else if (IsDebugBreakSlot()) { return IsDebugBreakAtSlot(); } else { return Debug::IsDebugBreak(rinfo()->target_address()); } } // Find the builtin to use for invoking the debug break static Handle DebugBreakForIC(Handle code, RelocInfo::Mode mode) { Isolate* isolate = code->GetIsolate(); // Find the builtin debug break function matching the calling convention // used by the call site. if (code->is_inline_cache_stub()) { switch (code->kind()) { case Code::CALL_IC: return isolate->builtins()->CallICStub_DebugBreak(); case Code::LOAD_IC: return isolate->builtins()->LoadIC_DebugBreak(); case Code::STORE_IC: return isolate->builtins()->StoreIC_DebugBreak(); case Code::KEYED_LOAD_IC: return isolate->builtins()->KeyedLoadIC_DebugBreak(); case Code::KEYED_STORE_IC: return isolate->builtins()->KeyedStoreIC_DebugBreak(); case Code::COMPARE_NIL_IC: return isolate->builtins()->CompareNilIC_DebugBreak(); default: UNREACHABLE(); } } if (RelocInfo::IsConstructCall(mode)) { if (code->has_function_cache()) { return isolate->builtins()->CallConstructStub_Recording_DebugBreak(); } else { return isolate->builtins()->CallConstructStub_DebugBreak(); } } if (code->kind() == Code::STUB) { ASSERT(code->major_key() == CodeStub::CallFunction); return isolate->builtins()->CallFunctionStub_DebugBreak(); } UNREACHABLE(); return Handle::null(); } void BreakLocationIterator::SetDebugBreakAtIC() { // Patch the original code with the current address as the current address // might have changed by the inline caching since the code was copied. original_rinfo()->set_target_address(rinfo()->target_address()); RelocInfo::Mode mode = rmode(); if (RelocInfo::IsCodeTarget(mode)) { Address target = rinfo()->target_address(); Handle target_code(Code::GetCodeFromTargetAddress(target)); // Patch the code to invoke the builtin debug break function matching the // calling convention used by the call site. Handle dbgbrk_code = DebugBreakForIC(target_code, mode); rinfo()->set_target_address(dbgbrk_code->entry()); } } void BreakLocationIterator::ClearDebugBreakAtIC() { // Patch the code to the original invoke. rinfo()->set_target_address(original_rinfo()->target_address()); } bool BreakLocationIterator::IsDebuggerStatement() { return RelocInfo::DEBUG_BREAK == rmode(); } bool BreakLocationIterator::IsDebugBreakSlot() { return RelocInfo::DEBUG_BREAK_SLOT == rmode(); } Object* BreakLocationIterator::BreakPointObjects() { return debug_info_->GetBreakPointObjects(code_position()); } // Clear out all the debug break code. This is ONLY supposed to be used when // shutting down the debugger as it will leave the break point information in // DebugInfo even though the code is patched back to the non break point state. void BreakLocationIterator::ClearAllDebugBreak() { while (!Done()) { ClearDebugBreak(); Next(); } } bool BreakLocationIterator::RinfoDone() const { ASSERT(reloc_iterator_->done() == reloc_iterator_original_->done()); return reloc_iterator_->done(); } void BreakLocationIterator::RinfoNext() { reloc_iterator_->next(); reloc_iterator_original_->next(); #ifdef DEBUG ASSERT(reloc_iterator_->done() == reloc_iterator_original_->done()); if (!reloc_iterator_->done()) { ASSERT(rmode() == original_rmode()); } #endif } // Threading support. void Debug::ThreadInit() { thread_local_.break_count_ = 0; thread_local_.break_id_ = 0; thread_local_.break_frame_id_ = StackFrame::NO_ID; thread_local_.last_step_action_ = StepNone; thread_local_.last_statement_position_ = RelocInfo::kNoPosition; thread_local_.step_count_ = 0; thread_local_.last_fp_ = 0; thread_local_.queued_step_count_ = 0; thread_local_.step_into_fp_ = 0; thread_local_.step_out_fp_ = 0; // TODO(isolates): frames_are_dropped_? thread_local_.current_debug_scope_ = NULL; thread_local_.restarter_frame_function_pointer_ = NULL; thread_local_.promise_on_stack_ = NULL; } char* Debug::ArchiveDebug(char* storage) { char* to = storage; MemCopy(to, reinterpret_cast(&thread_local_), sizeof(ThreadLocal)); ThreadInit(); return storage + ArchiveSpacePerThread(); } char* Debug::RestoreDebug(char* storage) { char* from = storage; MemCopy(reinterpret_cast(&thread_local_), from, sizeof(ThreadLocal)); return storage + ArchiveSpacePerThread(); } int Debug::ArchiveSpacePerThread() { return sizeof(ThreadLocal); } ScriptCache::ScriptCache(Isolate* isolate) : HashMap(HashMap::PointersMatch), isolate_(isolate), collected_scripts_(10) { Heap* heap = isolate_->heap(); HandleScope scope(isolate_); // Perform two GCs to get rid of all unreferenced scripts. The first GC gets // rid of all the cached script wrappers and the second gets rid of the // scripts which are no longer referenced. heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "ScriptCache"); heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "ScriptCache"); // Scan heap for Script objects. HeapIterator iterator(heap); DisallowHeapAllocation no_allocation; for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { if (obj->IsScript() && Script::cast(obj)->HasValidSource()) { Add(Handle 登录后可以享受更多权益 您还没有登录,登录后您可以: 收藏Android系统代码 收藏喜欢的文章 多个平台共享账号 去登录 首次使用?从这里 注册
(Code::GetCodeFromTargetAddress(original_target)); } bool is_call_function_stub = (maybe_call_function_stub->kind() == Code::STUB && maybe_call_function_stub->major_key() == CodeStub::CallFunction); // Step in through construct call requires no changes to the running code. // Step in through getters/setters should already be prepared as well // because caller of this function (Debug::PrepareStep) is expected to // flood the top frame's function with one shot breakpoints. // Step in through CallFunction stub should also be prepared by caller of // this function (Debug::PrepareStep) which should flood target function // with breakpoints. ASSERT(RelocInfo::IsConstructCall(rmode()) || target_code->is_inline_cache_stub() || is_call_function_stub); #endif } // Check whether the break point is at a position which will exit the function. bool BreakLocationIterator::IsExit() const { return (RelocInfo::IsJSReturn(rmode())); } bool BreakLocationIterator::HasBreakPoint() { return debug_info_->HasBreakPoint(code_position()); } // Check whether there is a debug break at the current position. bool BreakLocationIterator::IsDebugBreak() { if (RelocInfo::IsJSReturn(rmode())) { return IsDebugBreakAtReturn(); } else if (IsDebugBreakSlot()) { return IsDebugBreakAtSlot(); } else { return Debug::IsDebugBreak(rinfo()->target_address()); } } // Find the builtin to use for invoking the debug break static Handle DebugBreakForIC(Handle code, RelocInfo::Mode mode) { Isolate* isolate = code->GetIsolate(); // Find the builtin debug break function matching the calling convention // used by the call site. if (code->is_inline_cache_stub()) { switch (code->kind()) { case Code::CALL_IC: return isolate->builtins()->CallICStub_DebugBreak(); case Code::LOAD_IC: return isolate->builtins()->LoadIC_DebugBreak(); case Code::STORE_IC: return isolate->builtins()->StoreIC_DebugBreak(); case Code::KEYED_LOAD_IC: return isolate->builtins()->KeyedLoadIC_DebugBreak(); case Code::KEYED_STORE_IC: return isolate->builtins()->KeyedStoreIC_DebugBreak(); case Code::COMPARE_NIL_IC: return isolate->builtins()->CompareNilIC_DebugBreak(); default: UNREACHABLE(); } } if (RelocInfo::IsConstructCall(mode)) { if (code->has_function_cache()) { return isolate->builtins()->CallConstructStub_Recording_DebugBreak(); } else { return isolate->builtins()->CallConstructStub_DebugBreak(); } } if (code->kind() == Code::STUB) { ASSERT(code->major_key() == CodeStub::CallFunction); return isolate->builtins()->CallFunctionStub_DebugBreak(); } UNREACHABLE(); return Handle::null(); } void BreakLocationIterator::SetDebugBreakAtIC() { // Patch the original code with the current address as the current address // might have changed by the inline caching since the code was copied. original_rinfo()->set_target_address(rinfo()->target_address()); RelocInfo::Mode mode = rmode(); if (RelocInfo::IsCodeTarget(mode)) { Address target = rinfo()->target_address(); Handle target_code(Code::GetCodeFromTargetAddress(target)); // Patch the code to invoke the builtin debug break function matching the // calling convention used by the call site. Handle dbgbrk_code = DebugBreakForIC(target_code, mode); rinfo()->set_target_address(dbgbrk_code->entry()); } } void BreakLocationIterator::ClearDebugBreakAtIC() { // Patch the code to the original invoke. rinfo()->set_target_address(original_rinfo()->target_address()); } bool BreakLocationIterator::IsDebuggerStatement() { return RelocInfo::DEBUG_BREAK == rmode(); } bool BreakLocationIterator::IsDebugBreakSlot() { return RelocInfo::DEBUG_BREAK_SLOT == rmode(); } Object* BreakLocationIterator::BreakPointObjects() { return debug_info_->GetBreakPointObjects(code_position()); } // Clear out all the debug break code. This is ONLY supposed to be used when // shutting down the debugger as it will leave the break point information in // DebugInfo even though the code is patched back to the non break point state. void BreakLocationIterator::ClearAllDebugBreak() { while (!Done()) { ClearDebugBreak(); Next(); } } bool BreakLocationIterator::RinfoDone() const { ASSERT(reloc_iterator_->done() == reloc_iterator_original_->done()); return reloc_iterator_->done(); } void BreakLocationIterator::RinfoNext() { reloc_iterator_->next(); reloc_iterator_original_->next(); #ifdef DEBUG ASSERT(reloc_iterator_->done() == reloc_iterator_original_->done()); if (!reloc_iterator_->done()) { ASSERT(rmode() == original_rmode()); } #endif } // Threading support. void Debug::ThreadInit() { thread_local_.break_count_ = 0; thread_local_.break_id_ = 0; thread_local_.break_frame_id_ = StackFrame::NO_ID; thread_local_.last_step_action_ = StepNone; thread_local_.last_statement_position_ = RelocInfo::kNoPosition; thread_local_.step_count_ = 0; thread_local_.last_fp_ = 0; thread_local_.queued_step_count_ = 0; thread_local_.step_into_fp_ = 0; thread_local_.step_out_fp_ = 0; // TODO(isolates): frames_are_dropped_? thread_local_.current_debug_scope_ = NULL; thread_local_.restarter_frame_function_pointer_ = NULL; thread_local_.promise_on_stack_ = NULL; } char* Debug::ArchiveDebug(char* storage) { char* to = storage; MemCopy(to, reinterpret_cast(&thread_local_), sizeof(ThreadLocal)); ThreadInit(); return storage + ArchiveSpacePerThread(); } char* Debug::RestoreDebug(char* storage) { char* from = storage; MemCopy(reinterpret_cast(&thread_local_), from, sizeof(ThreadLocal)); return storage + ArchiveSpacePerThread(); } int Debug::ArchiveSpacePerThread() { return sizeof(ThreadLocal); } ScriptCache::ScriptCache(Isolate* isolate) : HashMap(HashMap::PointersMatch), isolate_(isolate), collected_scripts_(10) { Heap* heap = isolate_->heap(); HandleScope scope(isolate_); // Perform two GCs to get rid of all unreferenced scripts. The first GC gets // rid of all the cached script wrappers and the second gets rid of the // scripts which are no longer referenced. heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "ScriptCache"); heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "ScriptCache"); // Scan heap for Script objects. HeapIterator iterator(heap); DisallowHeapAllocation no_allocation; for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { if (obj->IsScript() && Script::cast(obj)->HasValidSource()) { Add(Handle 登录后可以享受更多权益 您还没有登录,登录后您可以: 收藏Android系统代码 收藏喜欢的文章 多个平台共享账号 去登录 首次使用?从这里 注册
DebugBreakForIC(Handle code, RelocInfo::Mode mode) { Isolate* isolate = code->GetIsolate(); // Find the builtin debug break function matching the calling convention // used by the call site. if (code->is_inline_cache_stub()) { switch (code->kind()) { case Code::CALL_IC: return isolate->builtins()->CallICStub_DebugBreak(); case Code::LOAD_IC: return isolate->builtins()->LoadIC_DebugBreak(); case Code::STORE_IC: return isolate->builtins()->StoreIC_DebugBreak(); case Code::KEYED_LOAD_IC: return isolate->builtins()->KeyedLoadIC_DebugBreak(); case Code::KEYED_STORE_IC: return isolate->builtins()->KeyedStoreIC_DebugBreak(); case Code::COMPARE_NIL_IC: return isolate->builtins()->CompareNilIC_DebugBreak(); default: UNREACHABLE(); } } if (RelocInfo::IsConstructCall(mode)) { if (code->has_function_cache()) { return isolate->builtins()->CallConstructStub_Recording_DebugBreak(); } else { return isolate->builtins()->CallConstructStub_DebugBreak(); } } if (code->kind() == Code::STUB) { ASSERT(code->major_key() == CodeStub::CallFunction); return isolate->builtins()->CallFunctionStub_DebugBreak(); } UNREACHABLE(); return Handle::null(); } void BreakLocationIterator::SetDebugBreakAtIC() { // Patch the original code with the current address as the current address // might have changed by the inline caching since the code was copied. original_rinfo()->set_target_address(rinfo()->target_address()); RelocInfo::Mode mode = rmode(); if (RelocInfo::IsCodeTarget(mode)) { Address target = rinfo()->target_address(); Handle target_code(Code::GetCodeFromTargetAddress(target)); // Patch the code to invoke the builtin debug break function matching the // calling convention used by the call site. Handle dbgbrk_code = DebugBreakForIC(target_code, mode); rinfo()->set_target_address(dbgbrk_code->entry()); } } void BreakLocationIterator::ClearDebugBreakAtIC() { // Patch the code to the original invoke. rinfo()->set_target_address(original_rinfo()->target_address()); } bool BreakLocationIterator::IsDebuggerStatement() { return RelocInfo::DEBUG_BREAK == rmode(); } bool BreakLocationIterator::IsDebugBreakSlot() { return RelocInfo::DEBUG_BREAK_SLOT == rmode(); } Object* BreakLocationIterator::BreakPointObjects() { return debug_info_->GetBreakPointObjects(code_position()); } // Clear out all the debug break code. This is ONLY supposed to be used when // shutting down the debugger as it will leave the break point information in // DebugInfo even though the code is patched back to the non break point state. void BreakLocationIterator::ClearAllDebugBreak() { while (!Done()) { ClearDebugBreak(); Next(); } } bool BreakLocationIterator::RinfoDone() const { ASSERT(reloc_iterator_->done() == reloc_iterator_original_->done()); return reloc_iterator_->done(); } void BreakLocationIterator::RinfoNext() { reloc_iterator_->next(); reloc_iterator_original_->next(); #ifdef DEBUG ASSERT(reloc_iterator_->done() == reloc_iterator_original_->done()); if (!reloc_iterator_->done()) { ASSERT(rmode() == original_rmode()); } #endif } // Threading support. void Debug::ThreadInit() { thread_local_.break_count_ = 0; thread_local_.break_id_ = 0; thread_local_.break_frame_id_ = StackFrame::NO_ID; thread_local_.last_step_action_ = StepNone; thread_local_.last_statement_position_ = RelocInfo::kNoPosition; thread_local_.step_count_ = 0; thread_local_.last_fp_ = 0; thread_local_.queued_step_count_ = 0; thread_local_.step_into_fp_ = 0; thread_local_.step_out_fp_ = 0; // TODO(isolates): frames_are_dropped_? thread_local_.current_debug_scope_ = NULL; thread_local_.restarter_frame_function_pointer_ = NULL; thread_local_.promise_on_stack_ = NULL; } char* Debug::ArchiveDebug(char* storage) { char* to = storage; MemCopy(to, reinterpret_cast(&thread_local_), sizeof(ThreadLocal)); ThreadInit(); return storage + ArchiveSpacePerThread(); } char* Debug::RestoreDebug(char* storage) { char* from = storage; MemCopy(reinterpret_cast(&thread_local_), from, sizeof(ThreadLocal)); return storage + ArchiveSpacePerThread(); } int Debug::ArchiveSpacePerThread() { return sizeof(ThreadLocal); } ScriptCache::ScriptCache(Isolate* isolate) : HashMap(HashMap::PointersMatch), isolate_(isolate), collected_scripts_(10) { Heap* heap = isolate_->heap(); HandleScope scope(isolate_); // Perform two GCs to get rid of all unreferenced scripts. The first GC gets // rid of all the cached script wrappers and the second gets rid of the // scripts which are no longer referenced. heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "ScriptCache"); heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "ScriptCache"); // Scan heap for Script objects. HeapIterator iterator(heap); DisallowHeapAllocation no_allocation; for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { if (obj->IsScript() && Script::cast(obj)->HasValidSource()) { Add(Handle 登录后可以享受更多权益 您还没有登录,登录后您可以: 收藏Android系统代码 收藏喜欢的文章 多个平台共享账号 去登录 首次使用?从这里 注册
code, RelocInfo::Mode mode) { Isolate* isolate = code->GetIsolate(); // Find the builtin debug break function matching the calling convention // used by the call site. if (code->is_inline_cache_stub()) { switch (code->kind()) { case Code::CALL_IC: return isolate->builtins()->CallICStub_DebugBreak(); case Code::LOAD_IC: return isolate->builtins()->LoadIC_DebugBreak(); case Code::STORE_IC: return isolate->builtins()->StoreIC_DebugBreak(); case Code::KEYED_LOAD_IC: return isolate->builtins()->KeyedLoadIC_DebugBreak(); case Code::KEYED_STORE_IC: return isolate->builtins()->KeyedStoreIC_DebugBreak(); case Code::COMPARE_NIL_IC: return isolate->builtins()->CompareNilIC_DebugBreak(); default: UNREACHABLE(); } } if (RelocInfo::IsConstructCall(mode)) { if (code->has_function_cache()) { return isolate->builtins()->CallConstructStub_Recording_DebugBreak(); } else { return isolate->builtins()->CallConstructStub_DebugBreak(); } } if (code->kind() == Code::STUB) { ASSERT(code->major_key() == CodeStub::CallFunction); return isolate->builtins()->CallFunctionStub_DebugBreak(); } UNREACHABLE(); return Handle::null(); } void BreakLocationIterator::SetDebugBreakAtIC() { // Patch the original code with the current address as the current address // might have changed by the inline caching since the code was copied. original_rinfo()->set_target_address(rinfo()->target_address()); RelocInfo::Mode mode = rmode(); if (RelocInfo::IsCodeTarget(mode)) { Address target = rinfo()->target_address(); Handle target_code(Code::GetCodeFromTargetAddress(target)); // Patch the code to invoke the builtin debug break function matching the // calling convention used by the call site. Handle dbgbrk_code = DebugBreakForIC(target_code, mode); rinfo()->set_target_address(dbgbrk_code->entry()); } } void BreakLocationIterator::ClearDebugBreakAtIC() { // Patch the code to the original invoke. rinfo()->set_target_address(original_rinfo()->target_address()); } bool BreakLocationIterator::IsDebuggerStatement() { return RelocInfo::DEBUG_BREAK == rmode(); } bool BreakLocationIterator::IsDebugBreakSlot() { return RelocInfo::DEBUG_BREAK_SLOT == rmode(); } Object* BreakLocationIterator::BreakPointObjects() { return debug_info_->GetBreakPointObjects(code_position()); } // Clear out all the debug break code. This is ONLY supposed to be used when // shutting down the debugger as it will leave the break point information in // DebugInfo even though the code is patched back to the non break point state. void BreakLocationIterator::ClearAllDebugBreak() { while (!Done()) { ClearDebugBreak(); Next(); } } bool BreakLocationIterator::RinfoDone() const { ASSERT(reloc_iterator_->done() == reloc_iterator_original_->done()); return reloc_iterator_->done(); } void BreakLocationIterator::RinfoNext() { reloc_iterator_->next(); reloc_iterator_original_->next(); #ifdef DEBUG ASSERT(reloc_iterator_->done() == reloc_iterator_original_->done()); if (!reloc_iterator_->done()) { ASSERT(rmode() == original_rmode()); } #endif } // Threading support. void Debug::ThreadInit() { thread_local_.break_count_ = 0; thread_local_.break_id_ = 0; thread_local_.break_frame_id_ = StackFrame::NO_ID; thread_local_.last_step_action_ = StepNone; thread_local_.last_statement_position_ = RelocInfo::kNoPosition; thread_local_.step_count_ = 0; thread_local_.last_fp_ = 0; thread_local_.queued_step_count_ = 0; thread_local_.step_into_fp_ = 0; thread_local_.step_out_fp_ = 0; // TODO(isolates): frames_are_dropped_? thread_local_.current_debug_scope_ = NULL; thread_local_.restarter_frame_function_pointer_ = NULL; thread_local_.promise_on_stack_ = NULL; } char* Debug::ArchiveDebug(char* storage) { char* to = storage; MemCopy(to, reinterpret_cast(&thread_local_), sizeof(ThreadLocal)); ThreadInit(); return storage + ArchiveSpacePerThread(); } char* Debug::RestoreDebug(char* storage) { char* from = storage; MemCopy(reinterpret_cast(&thread_local_), from, sizeof(ThreadLocal)); return storage + ArchiveSpacePerThread(); } int Debug::ArchiveSpacePerThread() { return sizeof(ThreadLocal); } ScriptCache::ScriptCache(Isolate* isolate) : HashMap(HashMap::PointersMatch), isolate_(isolate), collected_scripts_(10) { Heap* heap = isolate_->heap(); HandleScope scope(isolate_); // Perform two GCs to get rid of all unreferenced scripts. The first GC gets // rid of all the cached script wrappers and the second gets rid of the // scripts which are no longer referenced. heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "ScriptCache"); heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "ScriptCache"); // Scan heap for Script objects. HeapIterator iterator(heap); DisallowHeapAllocation no_allocation; for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { if (obj->IsScript() && Script::cast(obj)->HasValidSource()) { Add(Handle 登录后可以享受更多权益 您还没有登录,登录后您可以: 收藏Android系统代码 收藏喜欢的文章 多个平台共享账号 去登录 首次使用?从这里 注册
::null(); } void BreakLocationIterator::SetDebugBreakAtIC() { // Patch the original code with the current address as the current address // might have changed by the inline caching since the code was copied. original_rinfo()->set_target_address(rinfo()->target_address()); RelocInfo::Mode mode = rmode(); if (RelocInfo::IsCodeTarget(mode)) { Address target = rinfo()->target_address(); Handle target_code(Code::GetCodeFromTargetAddress(target)); // Patch the code to invoke the builtin debug break function matching the // calling convention used by the call site. Handle dbgbrk_code = DebugBreakForIC(target_code, mode); rinfo()->set_target_address(dbgbrk_code->entry()); } } void BreakLocationIterator::ClearDebugBreakAtIC() { // Patch the code to the original invoke. rinfo()->set_target_address(original_rinfo()->target_address()); } bool BreakLocationIterator::IsDebuggerStatement() { return RelocInfo::DEBUG_BREAK == rmode(); } bool BreakLocationIterator::IsDebugBreakSlot() { return RelocInfo::DEBUG_BREAK_SLOT == rmode(); } Object* BreakLocationIterator::BreakPointObjects() { return debug_info_->GetBreakPointObjects(code_position()); } // Clear out all the debug break code. This is ONLY supposed to be used when // shutting down the debugger as it will leave the break point information in // DebugInfo even though the code is patched back to the non break point state. void BreakLocationIterator::ClearAllDebugBreak() { while (!Done()) { ClearDebugBreak(); Next(); } } bool BreakLocationIterator::RinfoDone() const { ASSERT(reloc_iterator_->done() == reloc_iterator_original_->done()); return reloc_iterator_->done(); } void BreakLocationIterator::RinfoNext() { reloc_iterator_->next(); reloc_iterator_original_->next(); #ifdef DEBUG ASSERT(reloc_iterator_->done() == reloc_iterator_original_->done()); if (!reloc_iterator_->done()) { ASSERT(rmode() == original_rmode()); } #endif } // Threading support. void Debug::ThreadInit() { thread_local_.break_count_ = 0; thread_local_.break_id_ = 0; thread_local_.break_frame_id_ = StackFrame::NO_ID; thread_local_.last_step_action_ = StepNone; thread_local_.last_statement_position_ = RelocInfo::kNoPosition; thread_local_.step_count_ = 0; thread_local_.last_fp_ = 0; thread_local_.queued_step_count_ = 0; thread_local_.step_into_fp_ = 0; thread_local_.step_out_fp_ = 0; // TODO(isolates): frames_are_dropped_? thread_local_.current_debug_scope_ = NULL; thread_local_.restarter_frame_function_pointer_ = NULL; thread_local_.promise_on_stack_ = NULL; } char* Debug::ArchiveDebug(char* storage) { char* to = storage; MemCopy(to, reinterpret_cast(&thread_local_), sizeof(ThreadLocal)); ThreadInit(); return storage + ArchiveSpacePerThread(); } char* Debug::RestoreDebug(char* storage) { char* from = storage; MemCopy(reinterpret_cast(&thread_local_), from, sizeof(ThreadLocal)); return storage + ArchiveSpacePerThread(); } int Debug::ArchiveSpacePerThread() { return sizeof(ThreadLocal); } ScriptCache::ScriptCache(Isolate* isolate) : HashMap(HashMap::PointersMatch), isolate_(isolate), collected_scripts_(10) { Heap* heap = isolate_->heap(); HandleScope scope(isolate_); // Perform two GCs to get rid of all unreferenced scripts. The first GC gets // rid of all the cached script wrappers and the second gets rid of the // scripts which are no longer referenced. heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "ScriptCache"); heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "ScriptCache"); // Scan heap for Script objects. HeapIterator iterator(heap); DisallowHeapAllocation no_allocation; for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { if (obj->IsScript() && Script::cast(obj)->HasValidSource()) { Add(Handle 登录后可以享受更多权益 您还没有登录,登录后您可以: 收藏Android系统代码 收藏喜欢的文章 多个平台共享账号 去登录 首次使用?从这里 注册
target_code(Code::GetCodeFromTargetAddress(target)); // Patch the code to invoke the builtin debug break function matching the // calling convention used by the call site. Handle dbgbrk_code = DebugBreakForIC(target_code, mode); rinfo()->set_target_address(dbgbrk_code->entry()); } } void BreakLocationIterator::ClearDebugBreakAtIC() { // Patch the code to the original invoke. rinfo()->set_target_address(original_rinfo()->target_address()); } bool BreakLocationIterator::IsDebuggerStatement() { return RelocInfo::DEBUG_BREAK == rmode(); } bool BreakLocationIterator::IsDebugBreakSlot() { return RelocInfo::DEBUG_BREAK_SLOT == rmode(); } Object* BreakLocationIterator::BreakPointObjects() { return debug_info_->GetBreakPointObjects(code_position()); } // Clear out all the debug break code. This is ONLY supposed to be used when // shutting down the debugger as it will leave the break point information in // DebugInfo even though the code is patched back to the non break point state. void BreakLocationIterator::ClearAllDebugBreak() { while (!Done()) { ClearDebugBreak(); Next(); } } bool BreakLocationIterator::RinfoDone() const { ASSERT(reloc_iterator_->done() == reloc_iterator_original_->done()); return reloc_iterator_->done(); } void BreakLocationIterator::RinfoNext() { reloc_iterator_->next(); reloc_iterator_original_->next(); #ifdef DEBUG ASSERT(reloc_iterator_->done() == reloc_iterator_original_->done()); if (!reloc_iterator_->done()) { ASSERT(rmode() == original_rmode()); } #endif } // Threading support. void Debug::ThreadInit() { thread_local_.break_count_ = 0; thread_local_.break_id_ = 0; thread_local_.break_frame_id_ = StackFrame::NO_ID; thread_local_.last_step_action_ = StepNone; thread_local_.last_statement_position_ = RelocInfo::kNoPosition; thread_local_.step_count_ = 0; thread_local_.last_fp_ = 0; thread_local_.queued_step_count_ = 0; thread_local_.step_into_fp_ = 0; thread_local_.step_out_fp_ = 0; // TODO(isolates): frames_are_dropped_? thread_local_.current_debug_scope_ = NULL; thread_local_.restarter_frame_function_pointer_ = NULL; thread_local_.promise_on_stack_ = NULL; } char* Debug::ArchiveDebug(char* storage) { char* to = storage; MemCopy(to, reinterpret_cast(&thread_local_), sizeof(ThreadLocal)); ThreadInit(); return storage + ArchiveSpacePerThread(); } char* Debug::RestoreDebug(char* storage) { char* from = storage; MemCopy(reinterpret_cast(&thread_local_), from, sizeof(ThreadLocal)); return storage + ArchiveSpacePerThread(); } int Debug::ArchiveSpacePerThread() { return sizeof(ThreadLocal); } ScriptCache::ScriptCache(Isolate* isolate) : HashMap(HashMap::PointersMatch), isolate_(isolate), collected_scripts_(10) { Heap* heap = isolate_->heap(); HandleScope scope(isolate_); // Perform two GCs to get rid of all unreferenced scripts. The first GC gets // rid of all the cached script wrappers and the second gets rid of the // scripts which are no longer referenced. heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "ScriptCache"); heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "ScriptCache"); // Scan heap for Script objects. HeapIterator iterator(heap); DisallowHeapAllocation no_allocation; for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { if (obj->IsScript() && Script::cast(obj)->HasValidSource()) { Add(Handle 登录后可以享受更多权益 您还没有登录,登录后您可以: 收藏Android系统代码 收藏喜欢的文章 多个平台共享账号 去登录 首次使用?从这里 注册
dbgbrk_code = DebugBreakForIC(target_code, mode); rinfo()->set_target_address(dbgbrk_code->entry()); } } void BreakLocationIterator::ClearDebugBreakAtIC() { // Patch the code to the original invoke. rinfo()->set_target_address(original_rinfo()->target_address()); } bool BreakLocationIterator::IsDebuggerStatement() { return RelocInfo::DEBUG_BREAK == rmode(); } bool BreakLocationIterator::IsDebugBreakSlot() { return RelocInfo::DEBUG_BREAK_SLOT == rmode(); } Object* BreakLocationIterator::BreakPointObjects() { return debug_info_->GetBreakPointObjects(code_position()); } // Clear out all the debug break code. This is ONLY supposed to be used when // shutting down the debugger as it will leave the break point information in // DebugInfo even though the code is patched back to the non break point state. void BreakLocationIterator::ClearAllDebugBreak() { while (!Done()) { ClearDebugBreak(); Next(); } } bool BreakLocationIterator::RinfoDone() const { ASSERT(reloc_iterator_->done() == reloc_iterator_original_->done()); return reloc_iterator_->done(); } void BreakLocationIterator::RinfoNext() { reloc_iterator_->next(); reloc_iterator_original_->next(); #ifdef DEBUG ASSERT(reloc_iterator_->done() == reloc_iterator_original_->done()); if (!reloc_iterator_->done()) { ASSERT(rmode() == original_rmode()); } #endif } // Threading support. void Debug::ThreadInit() { thread_local_.break_count_ = 0; thread_local_.break_id_ = 0; thread_local_.break_frame_id_ = StackFrame::NO_ID; thread_local_.last_step_action_ = StepNone; thread_local_.last_statement_position_ = RelocInfo::kNoPosition; thread_local_.step_count_ = 0; thread_local_.last_fp_ = 0; thread_local_.queued_step_count_ = 0; thread_local_.step_into_fp_ = 0; thread_local_.step_out_fp_ = 0; // TODO(isolates): frames_are_dropped_? thread_local_.current_debug_scope_ = NULL; thread_local_.restarter_frame_function_pointer_ = NULL; thread_local_.promise_on_stack_ = NULL; } char* Debug::ArchiveDebug(char* storage) { char* to = storage; MemCopy(to, reinterpret_cast(&thread_local_), sizeof(ThreadLocal)); ThreadInit(); return storage + ArchiveSpacePerThread(); } char* Debug::RestoreDebug(char* storage) { char* from = storage; MemCopy(reinterpret_cast(&thread_local_), from, sizeof(ThreadLocal)); return storage + ArchiveSpacePerThread(); } int Debug::ArchiveSpacePerThread() { return sizeof(ThreadLocal); } ScriptCache::ScriptCache(Isolate* isolate) : HashMap(HashMap::PointersMatch), isolate_(isolate), collected_scripts_(10) { Heap* heap = isolate_->heap(); HandleScope scope(isolate_); // Perform two GCs to get rid of all unreferenced scripts. The first GC gets // rid of all the cached script wrappers and the second gets rid of the // scripts which are no longer referenced. heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "ScriptCache"); heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "ScriptCache"); // Scan heap for Script objects. HeapIterator iterator(heap); DisallowHeapAllocation no_allocation; for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { if (obj->IsScript() && Script::cast(obj)->HasValidSource()) { Add(Handle 登录后可以享受更多权益 您还没有登录,登录后您可以: 收藏Android系统代码 收藏喜欢的文章 多个平台共享账号 去登录 首次使用?从这里 注册
您还没有登录,登录后您可以:
首次使用?从这里 注册