LCOV - code coverage report
Current view: top level - test/cctest - trace-extension.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 63 64 98.4 %
Date: 2017-10-20 Functions: 12 12 100.0 %

          Line data    Source code
       1             : // Copyright 2014 the V8 project authors. All rights reserved.
       2             : // Redistribution and use in source and binary forms, with or without
       3             : // modification, are permitted provided that the following conditions are
       4             : // met:
       5             : //
       6             : //     * Redistributions of source code must retain the above copyright
       7             : //       notice, this list of conditions and the following disclaimer.
       8             : //     * Redistributions in binary form must reproduce the above
       9             : //       copyright notice, this list of conditions and the following
      10             : //       disclaimer in the documentation and/or other materials provided
      11             : //       with the distribution.
      12             : //     * Neither the name of Google Inc. nor the names of its
      13             : //       contributors may be used to endorse or promote products derived
      14             : //       from this software without specific prior written permission.
      15             : //
      16             : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
      17             : // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
      18             : // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
      19             : // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
      20             : // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
      21             : // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
      22             : // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      23             : // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      24             : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      25             : // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
      26             : // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      27             : 
      28             : #include "test/cctest/trace-extension.h"
      29             : 
      30             : #include "include/v8-profiler.h"
      31             : #include "src/vm-state-inl.h"
      32             : #include "test/cctest/cctest.h"
      33             : 
      34             : namespace v8 {
      35             : namespace internal {
      36             : 
      37             : const char* TraceExtension::kSource =
      38             :     "native function trace();"
      39             :     "native function js_trace();"
      40             :     "native function js_entry_sp();"
      41             :     "native function js_entry_sp_level2();";
      42             : 
      43             : 
      44          96 : v8::Local<v8::FunctionTemplate> TraceExtension::GetNativeFunctionTemplate(
      45             :     v8::Isolate* isolate, v8::Local<v8::String> name) {
      46          96 :   v8::Local<v8::Context> context = isolate->GetCurrentContext();
      47          96 :   if (name->Equals(context, v8::String::NewFromUtf8(isolate, "trace",
      48             :                                                     v8::NewStringType::kNormal)
      49         192 :                                 .ToLocalChecked())
      50         192 :           .FromJust()) {
      51          24 :     return v8::FunctionTemplate::New(isolate, TraceExtension::Trace);
      52          72 :   } else if (name->Equals(context,
      53             :                           v8::String::NewFromUtf8(isolate, "js_trace",
      54             :                                                   v8::NewStringType::kNormal)
      55         144 :                               .ToLocalChecked())
      56         144 :                  .FromJust()) {
      57          24 :     return v8::FunctionTemplate::New(isolate, TraceExtension::JSTrace);
      58          48 :   } else if (name->Equals(context,
      59             :                           v8::String::NewFromUtf8(isolate, "js_entry_sp",
      60             :                                                   v8::NewStringType::kNormal)
      61          96 :                               .ToLocalChecked())
      62          96 :                  .FromJust()) {
      63          24 :     return v8::FunctionTemplate::New(isolate, TraceExtension::JSEntrySP);
      64          24 :   } else if (name->Equals(context,
      65             :                           v8::String::NewFromUtf8(isolate, "js_entry_sp_level2",
      66             :                                                   v8::NewStringType::kNormal)
      67          48 :                               .ToLocalChecked())
      68          48 :                  .FromJust()) {
      69          24 :     return v8::FunctionTemplate::New(isolate, TraceExtension::JSEntrySPLevel2);
      70             :   } else {
      71           0 :     CHECK(false);
      72             :     return v8::Local<v8::FunctionTemplate>();
      73             :   }
      74             : }
      75             : 
      76             : 
      77          12 : Address TraceExtension::GetFP(const v8::FunctionCallbackInfo<v8::Value>& args) {
      78             :   // Convert frame pointer from encoding as smis in the arguments to a pointer.
      79          12 :   CHECK_EQ(2, args.Length());  // Ignore second argument on 32-bit platform.
      80             : #if defined(V8_HOST_ARCH_32_BIT)
      81             :   Address fp = *reinterpret_cast<Address*>(*args[0]);
      82             : #elif defined(V8_HOST_ARCH_64_BIT)
      83          12 :   int64_t low_bits = *reinterpret_cast<uint64_t*>(*args[0]) >> 32;
      84          12 :   int64_t high_bits = *reinterpret_cast<uint64_t*>(*args[1]);
      85          12 :   Address fp = reinterpret_cast<Address>(high_bits | low_bits);
      86             : #else
      87             : #error Host architecture is neither 32-bit nor 64-bit.
      88             : #endif
      89             :   printf("Trace: %p\n", static_cast<void*>(fp));
      90          12 :   return fp;
      91             : }
      92             : 
      93             : static struct { v8::TickSample* sample; } trace_env = {nullptr};
      94             : 
      95          18 : void TraceExtension::InitTraceEnv(v8::TickSample* sample) {
      96          18 :   trace_env.sample = sample;
      97          18 : }
      98             : 
      99             : 
     100          18 : void TraceExtension::DoTrace(Address fp) {
     101             :   RegisterState regs;
     102          18 :   regs.fp = fp;
     103             :   // sp is only used to define stack high bound
     104             :   regs.sp =
     105          18 :       reinterpret_cast<Address>(trace_env.sample) - 10240;
     106             :   trace_env.sample->Init(CcTest::isolate(), regs,
     107          18 :                          v8::TickSample::kSkipCEntryFrame, true);
     108          18 : }
     109             : 
     110             : 
     111           6 : void TraceExtension::Trace(const v8::FunctionCallbackInfo<v8::Value>& args) {
     112             :   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate());
     113           6 :   i::VMState<EXTERNAL> state(isolate);
     114             :   Address address = reinterpret_cast<Address>(
     115             :       reinterpret_cast<intptr_t>(&TraceExtension::Trace));
     116          12 :   i::ExternalCallbackScope call_scope(isolate, address);
     117          12 :   DoTrace(GetFP(args));
     118           6 : }
     119             : 
     120             : 
     121             : // Hide c_entry_fp to emulate situation when sampling is done while
     122             : // pure JS code is being executed
     123           6 : static void DoTraceHideCEntryFPAddress(Address fp) {
     124             :   v8::internal::Address saved_c_frame_fp =
     125           6 :       *(CcTest::i_isolate()->c_entry_fp_address());
     126           6 :   CHECK(saved_c_frame_fp);
     127           6 :   *(CcTest::i_isolate()->c_entry_fp_address()) = 0;
     128           6 :   i::TraceExtension::DoTrace(fp);
     129           6 :   *(CcTest::i_isolate()->c_entry_fp_address()) = saved_c_frame_fp;
     130           6 : }
     131             : 
     132             : 
     133           6 : void TraceExtension::JSTrace(const v8::FunctionCallbackInfo<v8::Value>& args) {
     134             :   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate());
     135           6 :   i::VMState<EXTERNAL> state(isolate);
     136             :   Address address = reinterpret_cast<Address>(
     137             :       reinterpret_cast<intptr_t>(&TraceExtension::JSTrace));
     138          12 :   i::ExternalCallbackScope call_scope(isolate, address);
     139          12 :   DoTraceHideCEntryFPAddress(GetFP(args));
     140           6 : }
     141             : 
     142             : 
     143          48 : Address TraceExtension::GetJsEntrySp() {
     144          48 :   CHECK(CcTest::i_isolate()->thread_local_top());
     145          48 :   return CcTest::i_isolate()->js_entry_sp();
     146             : }
     147             : 
     148             : 
     149          12 : void TraceExtension::JSEntrySP(
     150             :     const v8::FunctionCallbackInfo<v8::Value>& args) {
     151          12 :   CHECK(GetJsEntrySp());
     152          12 : }
     153             : 
     154             : 
     155           6 : void TraceExtension::JSEntrySPLevel2(
     156           6 :     const v8::FunctionCallbackInfo<v8::Value>& args) {
     157           6 :   v8::HandleScope scope(args.GetIsolate());
     158           6 :   const Address js_entry_sp = GetJsEntrySp();
     159           6 :   CHECK(js_entry_sp);
     160             :   CompileRun("js_entry_sp();");
     161           6 :   CHECK_EQ(js_entry_sp, GetJsEntrySp());
     162           6 : }
     163             : 
     164             : 
     165             : }  // namespace internal
     166       71154 : }  // namespace v8

Generated by: LCOV version 1.10