⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 log.cc.svn-base

📁 Google浏览器V8内核代码
💻 SVN-BASE
📖 第 1 页 / 共 2 页
字号:
// Copyright 2006-2008 the V8 project authors. All rights reserved.// Redistribution and use in source and binary forms, with or without// modification, are permitted provided that the following conditions are// met:////     * Redistributions of source code must retain the above copyright//       notice, this list of conditions and the following disclaimer.//     * Redistributions in binary form must reproduce the above//       copyright notice, this list of conditions and the following//       disclaimer in the documentation and/or other materials provided//       with the distribution.//     * Neither the name of Google Inc. nor the names of its//       contributors may be used to endorse or promote products derived//       from this software without specific prior written permission.//// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#include <stdarg.h>#include "v8.h"#include "log.h"#include "platform.h"namespace v8 { namespace internal {#ifdef ENABLE_LOGGING_AND_PROFILING//// Sliding state window.  Updates counters to keep track of the last// window of kBufferSize states.  This is useful to track where we// spent our time.//class SlidingStateWindow { public:  SlidingStateWindow();  ~SlidingStateWindow();  void AddState(StateTag state); private:  static const int kBufferSize = 256;  int current_index_;  bool is_full_;  byte buffer_[kBufferSize];  void IncrementStateCounter(StateTag state) {    Counters::state_counters[state].Increment();  }  void DecrementStateCounter(StateTag state) {    Counters::state_counters[state].Decrement();  }};//// The Profiler samples pc and sp values for the main thread.// Each sample is appended to a circular buffer.// An independent thread removes data and writes it to the log.// This design minimizes the time spent in the sampler.//class Profiler: public Thread { public:  Profiler();  void Engage();  void Disengage();  // Inserts collected profiling data into buffer.  void Insert(TickSample* sample) {    if (Succ(head_) == tail_) {      overflow_ = true;    } else {      buffer_[head_] = *sample;      head_ = Succ(head_);      buffer_semaphore_->Signal();  // Tell we have an element.    }  }  // Waits for a signal and removes profiling data.  bool Remove(TickSample* sample) {    buffer_semaphore_->Wait();  // Wait for an element.    *sample = buffer_[tail_];    bool result = overflow_;    tail_ = Succ(tail_);    overflow_ = false;    return result;  }  void Run(); private:  // Returns the next index in the cyclic buffer.  int Succ(int index) { return (index + 1) % kBufferSize; }  // Cyclic buffer for communicating profiling samples  // between the signal handler and the worker thread.  static const int kBufferSize = 128;  TickSample buffer_[kBufferSize];  // Buffer storage.  int head_;  // Index to the buffer head.  int tail_;  // Index to the buffer tail.  bool overflow_;  // Tell whether a buffer overflow has occurred.  Semaphore* buffer_semaphore_;  // Sempahore used for buffer synchronization.  // Tells whether worker thread should continue running.  bool running_;};//// Ticker used to provide ticks to the profiler and the sliding state// window.//class Ticker: public Sampler { public:  explicit Ticker(int interval):      Sampler(interval, FLAG_prof), window_(NULL), profiler_(NULL) {}  ~Ticker() { if (IsActive()) Stop(); }  void Tick(TickSample* sample) {    if (profiler_) profiler_->Insert(sample);    if (window_) window_->AddState(sample->state);  }  void SetWindow(SlidingStateWindow* window) {    window_ = window;    if (!IsActive()) Start();  }  void ClearWindow() {    window_ = NULL;    if (!profiler_ && IsActive()) Stop();  }  void SetProfiler(Profiler* profiler) {    profiler_ = profiler;    if (!IsActive()) Start();  }  void ClearProfiler() {    profiler_ = NULL;    if (!window_ && IsActive()) Stop();  } private:  SlidingStateWindow* window_;  Profiler* profiler_;};//// SlidingStateWindow implementation.//SlidingStateWindow::SlidingStateWindow(): current_index_(0), is_full_(false) {  for (int i = 0; i < kBufferSize; i++) {    buffer_[i] = static_cast<byte>(OTHER);  }  Logger::ticker_->SetWindow(this);}SlidingStateWindow::~SlidingStateWindow() {  Logger::ticker_->ClearWindow();}void SlidingStateWindow::AddState(StateTag state) {  if (is_full_) {    DecrementStateCounter(static_cast<StateTag>(buffer_[current_index_]));  } else if (current_index_ == kBufferSize - 1) {    is_full_ = true;  }  buffer_[current_index_] = static_cast<byte>(state);  IncrementStateCounter(state);  ASSERT(IsPowerOf2(kBufferSize));  current_index_ = (current_index_ + 1) & (kBufferSize - 1);}//// Profiler implementation.//Profiler::Profiler() {  buffer_semaphore_ = OS::CreateSemaphore(0);  head_ = 0;  tail_ = 0;  overflow_ = false;  running_ = false;}void Profiler::Engage() {  OS::LogSharedLibraryAddresses();  // Start thread processing the profiler buffer.  running_ = true;  Start();  // Register to get ticks.  Logger::ticker_->SetProfiler(this);  LOG(StringEvent("profiler", "begin"));}void Profiler::Disengage() {  // Stop receiving ticks.  Logger::ticker_->ClearProfiler();  // Terminate the worker thread by setting running_ to false,  // inserting a fake element in the queue and then wait for  // the thread to terminate.  running_ = false;  TickSample sample;  sample.pc = 0;  sample.sp = 0;  sample.state = OTHER;  Insert(&sample);  Join();  LOG(StringEvent("profiler", "end"));}void Profiler::Run() {  TickSample sample;  bool overflow = Logger::profiler_->Remove(&sample);  while (running_) {    LOG(TickEvent(&sample, overflow));    overflow = Logger::profiler_->Remove(&sample);  }}//// Logger class implementation.//Ticker* Logger::ticker_ = NULL;FILE* Logger::logfile_ = NULL;Profiler* Logger::profiler_ = NULL;Mutex* Logger::mutex_ = NULL;VMState* Logger::current_state_ = NULL;SlidingStateWindow* Logger::sliding_state_window_ = NULL;#endif  // ENABLE_LOGGING_AND_PROFILINGvoid Logger::Preamble(const char* content) {#ifdef ENABLE_LOGGING_AND_PROFILING  if (logfile_ == NULL) return;  ScopedLock sl(mutex_);  fprintf(logfile_, "%s", content);#endif}void Logger::StringEvent(const char* name, const char* value) {#ifdef ENABLE_LOGGING_AND_PROFILING  if (logfile_ == NULL) return;  ScopedLock sl(mutex_);  fprintf(logfile_, "%s,\"%s\"\n", name, value);#endif}void Logger::IntEvent(const char* name, int value) {#ifdef ENABLE_LOGGING_AND_PROFILING  if (logfile_ == NULL) return;  ScopedLock sl(mutex_);  fprintf(logfile_, "%s,%d\n", name, value);#endif}void Logger::HandleEvent(const char* name, Object** location) {#ifdef ENABLE_LOGGING_AND_PROFILING  if (logfile_ == NULL || !FLAG_log_handles) return;  ScopedLock sl(mutex_);  fprintf(logfile_, "%s,0x%x\n", name,          reinterpret_cast<unsigned int>(location));#endif}#ifdef ENABLE_LOGGING_AND_PROFILING// ApiEvent is private so all the calls come from the Logger class.  It is the// caller's responsibility to ensure that logfile_ is not NULL and that// FLAG_log_api is true.void Logger::ApiEvent(const char* format, ...) {  ASSERT(logfile_ != NULL && FLAG_log_api);  ScopedLock sl(mutex_);  va_list ap;  va_start(ap, format);  vfprintf(logfile_, format, ap);}#endifvoid Logger::ApiNamedSecurityCheck(Object* key) {#ifdef ENABLE_LOGGING_AND_PROFILING  if (logfile_ == NULL || !FLAG_log_api) return;  if (key->IsString()) {    SmartPointer<char> str =        String::cast(key)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);    ApiEvent("api,check-security,\"%s\"\n", *str);  } else if (key->IsUndefined()) {    ApiEvent("api,check-security,undefined\n");  } else {    ApiEvent("api,check-security,['no-name']\n");  }#endif}void Logger::SharedLibraryEvent(const char* library_path,                                unsigned start,                                unsigned end) {#ifdef ENABLE_LOGGING_AND_PROFILING  if (logfile_ == NULL || !FLAG_prof) return;  ScopedLock sl(mutex_);  fprintf(logfile_, "shared-library,\"%s\",0x%08x,0x%08x\n", library_path,          start, end);#endif}void Logger::SharedLibraryEvent(const wchar_t* library_path,                                unsigned start,                                unsigned end) {#ifdef ENABLE_LOGGING_AND_PROFILING  if (logfile_ == NULL || !FLAG_prof) return;  ScopedLock sl(mutex_);  fprintf(logfile_, "shared-library,\"%ls\",0x%08x,0x%08x\n", library_path,          start, end);#endif}#ifdef ENABLE_LOGGING_AND_PROFILINGvoid Logger::LogRegExpSource(Handle<JSRegExp> regexp) {  // Prints "/" + re.source + "/" +  //      (re.global?"g":"") + (re.ignorecase?"i":"") + (re.multiline?"m":"")  Handle<Object> source = GetProperty(regexp, "source");  if (!source->IsString()) {    fprintf(logfile_, "no source");    return;  }  Handle<String> source_string = Handle<String>::cast(source);  SmartPointer<uc16> cstring = source_string->ToWideCString();  fprintf(logfile_, "/");  for (int i = 0, n = source_string->length(); i < n; i++) {    uc16 c = cstring[i];    if (c < 32 || (c > 126 && c <= 255)) {      fprintf(logfile_, "\\x%02x", c);    } else if (c > 255) {      fprintf(logfile_, "\\u%04x", c);    } else {      fprintf(logfile_, "%lc", c);    }  }  fprintf(logfile_, "/");  // global flag  Handle<Object> global = GetProperty(regexp, "global");  if (global->IsTrue()) {    fprintf(logfile_, "g");  }  // ignorecase flag  Handle<Object> ignorecase = GetProperty(regexp, "ignoreCase");  if (ignorecase->IsTrue()) {    fprintf(logfile_, "i");  }  // multiline flag  Handle<Object> multiline = GetProperty(regexp, "multiline");  if (multiline->IsTrue()) {    fprintf(logfile_, "m");  }}#endif  // ENABLE_LOGGING_AND_PROFILINGvoid Logger::RegExpCompileEvent(Handle<JSRegExp> regexp) {#ifdef ENABLE_LOGGING_AND_PROFILING  if (logfile_ == NULL || !FLAG_log_regexp) return;  ScopedLock sl(mutex_);  fprintf(logfile_, "regexp-compile,");  LogRegExpSource(regexp);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -