| Index: test/cctest/test-log-ia32.cc
 | 
| diff --git a/test/cctest/test-log-ia32.cc b/test/cctest/test-log-ia32.cc
 | 
| deleted file mode 100644
 | 
| index a40a800ee3a55c070eddafcf5ee7c05b8b9d6cfd..0000000000000000000000000000000000000000
 | 
| --- a/test/cctest/test-log-ia32.cc
 | 
| +++ /dev/null
 | 
| @@ -1,370 +0,0 @@
 | 
| -// Copyright 2006-2009 the V8 project authors. All rights reserved.
 | 
| -//
 | 
| -// Tests of profiler-related functions from log.h
 | 
| -
 | 
| -#ifdef ENABLE_LOGGING_AND_PROFILING
 | 
| -
 | 
| -#include <stdlib.h>
 | 
| -
 | 
| -#include "v8.h"
 | 
| -
 | 
| -#include "codegen.h"
 | 
| -#include "log.h"
 | 
| -#include "top.h"
 | 
| -#include "cctest.h"
 | 
| -#include "disassembler.h"
 | 
| -#include "register-allocator-inl.h"
 | 
| -
 | 
| -using v8::Function;
 | 
| -using v8::Local;
 | 
| -using v8::Object;
 | 
| -using v8::Script;
 | 
| -using v8::String;
 | 
| -using v8::Value;
 | 
| -
 | 
| -using v8::internal::byte;
 | 
| -using v8::internal::Address;
 | 
| -using v8::internal::Handle;
 | 
| -using v8::internal::JSFunction;
 | 
| -using v8::internal::StackTracer;
 | 
| -using v8::internal::TickSample;
 | 
| -using v8::internal::Top;
 | 
| -
 | 
| -namespace i = v8::internal;
 | 
| -
 | 
| -
 | 
| -static v8::Persistent<v8::Context> env;
 | 
| -
 | 
| -
 | 
| -static struct {
 | 
| -  TickSample* sample;
 | 
| -} trace_env = { NULL };
 | 
| -
 | 
| -
 | 
| -static void InitTraceEnv(TickSample* sample) {
 | 
| -  trace_env.sample = sample;
 | 
| -}
 | 
| -
 | 
| -
 | 
| -static void DoTrace(Address fp) {
 | 
| -  trace_env.sample->fp = reinterpret_cast<uintptr_t>(fp);
 | 
| -  // sp is only used to define stack high bound
 | 
| -  trace_env.sample->sp =
 | 
| -      reinterpret_cast<unsigned int>(trace_env.sample) - 10240;
 | 
| -  StackTracer::Trace(trace_env.sample);
 | 
| -}
 | 
| -
 | 
| -
 | 
| -// Hide c_entry_fp to emulate situation when sampling is done while
 | 
| -// pure JS code is being executed
 | 
| -static void DoTraceHideCEntryFPAddress(Address fp) {
 | 
| -  v8::internal::Address saved_c_frame_fp = *(Top::c_entry_fp_address());
 | 
| -  CHECK(saved_c_frame_fp);
 | 
| -  *(Top::c_entry_fp_address()) = 0;
 | 
| -  DoTrace(fp);
 | 
| -  *(Top::c_entry_fp_address()) = saved_c_frame_fp;
 | 
| -}
 | 
| -
 | 
| -
 | 
| -static void CheckRetAddrIsInFunction(const char* func_name,
 | 
| -                                     Address ret_addr,
 | 
| -                                     Address func_start_addr,
 | 
| -                                     unsigned int func_len) {
 | 
| -  printf("CheckRetAddrIsInFunction \"%s\": %p %p %p\n",
 | 
| -         func_name, func_start_addr, ret_addr, func_start_addr + func_len);
 | 
| -  CHECK_GE(ret_addr, func_start_addr);
 | 
| -  CHECK_GE(func_start_addr + func_len, ret_addr);
 | 
| -}
 | 
| -
 | 
| -
 | 
| -static void CheckRetAddrIsInJSFunction(const char* func_name,
 | 
| -                                       Address ret_addr,
 | 
| -                                       Handle<JSFunction> func) {
 | 
| -  v8::internal::Code* func_code = func->code();
 | 
| -  CheckRetAddrIsInFunction(
 | 
| -      func_name, ret_addr,
 | 
| -      func_code->instruction_start(),
 | 
| -      func_code->ExecutableSize());
 | 
| -}
 | 
| -
 | 
| -
 | 
| -// --- T r a c e   E x t e n s i o n ---
 | 
| -
 | 
| -class TraceExtension : public v8::Extension {
 | 
| - public:
 | 
| -  TraceExtension() : v8::Extension("v8/trace", kSource) { }
 | 
| -  virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction(
 | 
| -      v8::Handle<String> name);
 | 
| -  static v8::Handle<v8::Value> Trace(const v8::Arguments& args);
 | 
| -  static v8::Handle<v8::Value> JSTrace(const v8::Arguments& args);
 | 
| -  static v8::Handle<v8::Value> JSEntrySP(const v8::Arguments& args);
 | 
| -  static v8::Handle<v8::Value> JSEntrySPLevel2(const v8::Arguments& args);
 | 
| - private:
 | 
| -  static Address GetFP(const v8::Arguments& args);
 | 
| -  static const char* kSource;
 | 
| -};
 | 
| -
 | 
| -
 | 
| -const char* TraceExtension::kSource =
 | 
| -    "native function trace();"
 | 
| -    "native function js_trace();"
 | 
| -    "native function js_entry_sp();"
 | 
| -    "native function js_entry_sp_level2();";
 | 
| -
 | 
| -v8::Handle<v8::FunctionTemplate> TraceExtension::GetNativeFunction(
 | 
| -    v8::Handle<String> name) {
 | 
| -  if (name->Equals(String::New("trace"))) {
 | 
| -    return v8::FunctionTemplate::New(TraceExtension::Trace);
 | 
| -  } else if (name->Equals(String::New("js_trace"))) {
 | 
| -    return v8::FunctionTemplate::New(TraceExtension::JSTrace);
 | 
| -  } else if (name->Equals(String::New("js_entry_sp"))) {
 | 
| -    return v8::FunctionTemplate::New(TraceExtension::JSEntrySP);
 | 
| -  } else if (name->Equals(String::New("js_entry_sp_level2"))) {
 | 
| -    return v8::FunctionTemplate::New(TraceExtension::JSEntrySPLevel2);
 | 
| -  } else {
 | 
| -    CHECK(false);
 | 
| -    return v8::Handle<v8::FunctionTemplate>();
 | 
| -  }
 | 
| -}
 | 
| -
 | 
| -
 | 
| -Address TraceExtension::GetFP(const v8::Arguments& args) {
 | 
| -  CHECK_EQ(1, args.Length());
 | 
| -  Address fp = reinterpret_cast<Address>(args[0]->Int32Value() << 2);
 | 
| -  printf("Trace: %p\n", fp);
 | 
| -  return fp;
 | 
| -}
 | 
| -
 | 
| -
 | 
| -v8::Handle<v8::Value> TraceExtension::Trace(const v8::Arguments& args) {
 | 
| -  DoTrace(GetFP(args));
 | 
| -  return v8::Undefined();
 | 
| -}
 | 
| -
 | 
| -
 | 
| -v8::Handle<v8::Value> TraceExtension::JSTrace(const v8::Arguments& args) {
 | 
| -  DoTraceHideCEntryFPAddress(GetFP(args));
 | 
| -  return v8::Undefined();
 | 
| -}
 | 
| -
 | 
| -
 | 
| -static Address GetJsEntrySp() {
 | 
| -  CHECK_NE(NULL, Top::GetCurrentThread());
 | 
| -  return Top::js_entry_sp(Top::GetCurrentThread());
 | 
| -}
 | 
| -
 | 
| -
 | 
| -v8::Handle<v8::Value> TraceExtension::JSEntrySP(const v8::Arguments& args) {
 | 
| -  CHECK_NE(0, GetJsEntrySp());
 | 
| -  return v8::Undefined();
 | 
| -}
 | 
| -
 | 
| -
 | 
| -static void CompileRun(const char* source) {
 | 
| -  Script::Compile(String::New(source))->Run();
 | 
| -}
 | 
| -
 | 
| -
 | 
| -v8::Handle<v8::Value> TraceExtension::JSEntrySPLevel2(
 | 
| -    const v8::Arguments& args) {
 | 
| -  v8::HandleScope scope;
 | 
| -  const Address js_entry_sp = GetJsEntrySp();
 | 
| -  CHECK_NE(0, js_entry_sp);
 | 
| -  CompileRun("js_entry_sp();");
 | 
| -  CHECK_EQ(js_entry_sp, GetJsEntrySp());
 | 
| -  return v8::Undefined();
 | 
| -}
 | 
| -
 | 
| -
 | 
| -static TraceExtension kTraceExtension;
 | 
| -v8::DeclareExtension kTraceExtensionDeclaration(&kTraceExtension);
 | 
| -
 | 
| -
 | 
| -static void InitializeVM() {
 | 
| -  if (env.IsEmpty()) {
 | 
| -    v8::HandleScope scope;
 | 
| -    const char* extensions[] = { "v8/trace" };
 | 
| -    v8::ExtensionConfiguration config(1, extensions);
 | 
| -    env = v8::Context::New(&config);
 | 
| -  }
 | 
| -  v8::HandleScope scope;
 | 
| -  env->Enter();
 | 
| -}
 | 
| -
 | 
| -
 | 
| -static Handle<JSFunction> CompileFunction(const char* source) {
 | 
| -  return v8::Utils::OpenHandle(*Script::Compile(String::New(source)));
 | 
| -}
 | 
| -
 | 
| -
 | 
| -static Local<Value> GetGlobalProperty(const char* name) {
 | 
| -  return env->Global()->Get(String::New(name));
 | 
| -}
 | 
| -
 | 
| -
 | 
| -static Handle<JSFunction> GetGlobalJSFunction(const char* name) {
 | 
| -  Handle<JSFunction> js_func(JSFunction::cast(
 | 
| -                                 *(v8::Utils::OpenHandle(
 | 
| -                                       *GetGlobalProperty(name)))));
 | 
| -  return js_func;
 | 
| -}
 | 
| -
 | 
| -
 | 
| -static void CheckRetAddrIsInJSFunction(const char* func_name,
 | 
| -                                       Address ret_addr) {
 | 
| -  CheckRetAddrIsInJSFunction(func_name, ret_addr,
 | 
| -                             GetGlobalJSFunction(func_name));
 | 
| -}
 | 
| -
 | 
| -
 | 
| -static void SetGlobalProperty(const char* name, Local<Value> value) {
 | 
| -  env->Global()->Set(String::New(name), value);
 | 
| -}
 | 
| -
 | 
| -
 | 
| -static Handle<v8::internal::String> NewString(const char* s) {
 | 
| -  return i::Factory::NewStringFromAscii(i::CStrVector(s));
 | 
| -}
 | 
| -
 | 
| -
 | 
| -namespace v8 {
 | 
| -namespace internal {
 | 
| -
 | 
| -class CodeGeneratorPatcher {
 | 
| - public:
 | 
| -  CodeGeneratorPatcher() {
 | 
| -    CodeGenerator::InlineRuntimeLUT genGetFramePointer =
 | 
| -        {&CodeGenerator::GenerateGetFramePointer, "_GetFramePointer"};
 | 
| -    // _FastCharCodeAt is not used in our tests.
 | 
| -    bool result = CodeGenerator::PatchInlineRuntimeEntry(
 | 
| -        NewString("_FastCharCodeAt"),
 | 
| -        genGetFramePointer, &oldInlineEntry);
 | 
| -    CHECK(result);
 | 
| -  }
 | 
| -
 | 
| -  ~CodeGeneratorPatcher() {
 | 
| -    CHECK(CodeGenerator::PatchInlineRuntimeEntry(
 | 
| -        NewString("_GetFramePointer"),
 | 
| -        oldInlineEntry, NULL));
 | 
| -  }
 | 
| -
 | 
| - private:
 | 
| -  CodeGenerator::InlineRuntimeLUT oldInlineEntry;
 | 
| -};
 | 
| -
 | 
| -} }  // namespace v8::internal
 | 
| -
 | 
| -
 | 
| -// Creates a global function named 'func_name' that calls the tracing
 | 
| -// function 'trace_func_name' with an actual EBP register value,
 | 
| -// shifted right to be presented as Smi.
 | 
| -static void CreateTraceCallerFunction(const char* func_name,
 | 
| -                                      const char* trace_func_name) {
 | 
| -  i::EmbeddedVector<char, 256> trace_call_buf;
 | 
| -  i::OS::SNPrintF(trace_call_buf, "%s(%%_GetFramePointer());", trace_func_name);
 | 
| -
 | 
| -  // Compile the script.
 | 
| -  i::CodeGeneratorPatcher patcher;
 | 
| -  bool allow_natives_syntax = i::FLAG_allow_natives_syntax;
 | 
| -  i::FLAG_allow_natives_syntax = true;
 | 
| -  Handle<JSFunction> func = CompileFunction(trace_call_buf.start());
 | 
| -  CHECK(!func.is_null());
 | 
| -  i::FLAG_allow_natives_syntax = allow_natives_syntax;
 | 
| -
 | 
| -#ifdef DEBUG
 | 
| -  v8::internal::Code* func_code = func->code();
 | 
| -  CHECK(func_code->IsCode());
 | 
| -  func_code->Print();
 | 
| -#endif
 | 
| -
 | 
| -  SetGlobalProperty(func_name, v8::ToApi<Value>(func));
 | 
| -}
 | 
| -
 | 
| -
 | 
| -TEST(CFromJSStackTrace) {
 | 
| -  TickSample sample;
 | 
| -  InitTraceEnv(&sample);
 | 
| -
 | 
| -  InitializeVM();
 | 
| -  v8::HandleScope scope;
 | 
| -  CreateTraceCallerFunction("JSFuncDoTrace", "trace");
 | 
| -  CompileRun(
 | 
| -      "function JSTrace() {"
 | 
| -      "         JSFuncDoTrace();"
 | 
| -      "};\n"
 | 
| -      "JSTrace();");
 | 
| -  CHECK_GT(sample.frames_count, 1);
 | 
| -  // Stack sampling will start from the first JS function, i.e. "JSFuncDoTrace"
 | 
| -  CheckRetAddrIsInJSFunction("JSFuncDoTrace",
 | 
| -                             sample.stack[0]);
 | 
| -  CheckRetAddrIsInJSFunction("JSTrace",
 | 
| -                             sample.stack[1]);
 | 
| -}
 | 
| -
 | 
| -
 | 
| -TEST(PureJSStackTrace) {
 | 
| -  TickSample sample;
 | 
| -  InitTraceEnv(&sample);
 | 
| -
 | 
| -  InitializeVM();
 | 
| -  v8::HandleScope scope;
 | 
| -  CreateTraceCallerFunction("JSFuncDoTrace", "js_trace");
 | 
| -  CompileRun(
 | 
| -      "function JSTrace() {"
 | 
| -      "         JSFuncDoTrace();"
 | 
| -      "};\n"
 | 
| -      "function OuterJSTrace() {"
 | 
| -      "         JSTrace();"
 | 
| -      "};\n"
 | 
| -      "OuterJSTrace();");
 | 
| -  CHECK_GT(sample.frames_count, 1);
 | 
| -  // Stack sampling will start from the caller of JSFuncDoTrace, i.e. "JSTrace"
 | 
| -  CheckRetAddrIsInJSFunction("JSTrace",
 | 
| -                             sample.stack[0]);
 | 
| -  CheckRetAddrIsInJSFunction("OuterJSTrace",
 | 
| -                             sample.stack[1]);
 | 
| -}
 | 
| -
 | 
| -
 | 
| -static void CFuncDoTrace() {
 | 
| -  Address fp;
 | 
| -#ifdef __GNUC__
 | 
| -  fp = reinterpret_cast<Address>(__builtin_frame_address(0));
 | 
| -#elif defined _MSC_VER
 | 
| -  __asm mov [fp], ebp  // NOLINT
 | 
| -#endif
 | 
| -  DoTrace(fp);
 | 
| -}
 | 
| -
 | 
| -
 | 
| -static int CFunc(int depth) {
 | 
| -  if (depth <= 0) {
 | 
| -    CFuncDoTrace();
 | 
| -    return 0;
 | 
| -  } else {
 | 
| -    return CFunc(depth - 1) + 1;
 | 
| -  }
 | 
| -}
 | 
| -
 | 
| -
 | 
| -TEST(PureCStackTrace) {
 | 
| -  TickSample sample;
 | 
| -  InitTraceEnv(&sample);
 | 
| -  // Check that sampler doesn't crash
 | 
| -  CHECK_EQ(10, CFunc(10));
 | 
| -}
 | 
| -
 | 
| -
 | 
| -TEST(JsEntrySp) {
 | 
| -  InitializeVM();
 | 
| -  v8::HandleScope scope;
 | 
| -  CHECK_EQ(0, GetJsEntrySp());
 | 
| -  CompileRun("a = 1; b = a + 1;");
 | 
| -  CHECK_EQ(0, GetJsEntrySp());
 | 
| -  CompileRun("js_entry_sp();");
 | 
| -  CHECK_EQ(0, GetJsEntrySp());
 | 
| -  CompileRun("js_entry_sp_level2();");
 | 
| -  CHECK_EQ(0, GetJsEntrySp());
 | 
| -}
 | 
| -
 | 
| -#endif  // ENABLE_LOGGING_AND_PROFILING
 | 
| 
 |