LCOV - code coverage report
Current view: top level - test/cctest - trace-extension.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 61 62 98.4 %
Date: 2019-04-17 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/objects/smi.h"
      32             : #include "src/vm-state-inl.h"
      33             : #include "test/cctest/cctest.h"
      34             : 
      35             : namespace v8 {
      36             : namespace internal {
      37             : 
      38             : const char* TraceExtension::kSource =
      39             :     "native function trace();"
      40             :     "native function js_trace();"
      41             :     "native function js_entry_sp();"
      42             :     "native function js_entry_sp_level2();";
      43             : 
      44             : 
      45          80 : v8::Local<v8::FunctionTemplate> TraceExtension::GetNativeFunctionTemplate(
      46             :     v8::Isolate* isolate, v8::Local<v8::String> name) {
      47          80 :   if (name->StrictEquals(
      48          80 :           v8::String::NewFromUtf8(isolate, "trace", v8::NewStringType::kNormal)
      49             :               .ToLocalChecked())) {
      50          20 :     return v8::FunctionTemplate::New(isolate, TraceExtension::Trace);
      51          60 :   } else if (name->StrictEquals(
      52          60 :                  v8::String::NewFromUtf8(isolate, "js_trace",
      53             :                                          v8::NewStringType::kNormal)
      54             :                      .ToLocalChecked())) {
      55          20 :     return v8::FunctionTemplate::New(isolate, TraceExtension::JSTrace);
      56          40 :   } else if (name->StrictEquals(
      57          40 :                  v8::String::NewFromUtf8(isolate, "js_entry_sp",
      58             :                                          v8::NewStringType::kNormal)
      59             :                      .ToLocalChecked())) {
      60          20 :     return v8::FunctionTemplate::New(isolate, TraceExtension::JSEntrySP);
      61          20 :   } else if (name->StrictEquals(
      62          20 :                  v8::String::NewFromUtf8(isolate, "js_entry_sp_level2",
      63             :                                          v8::NewStringType::kNormal)
      64             :                      .ToLocalChecked())) {
      65          20 :     return v8::FunctionTemplate::New(isolate, TraceExtension::JSEntrySPLevel2);
      66             :   }
      67           0 :   UNREACHABLE();
      68             : }
      69             : 
      70             : 
      71          10 : Address TraceExtension::GetFP(const v8::FunctionCallbackInfo<v8::Value>& args) {
      72             :   // Convert frame pointer from encoding as smis in the arguments to a pointer.
      73          10 :   CHECK_EQ(2, args.Length());  // Ignore second argument on 32-bit platform.
      74             : #if defined(V8_HOST_ARCH_32_BIT)
      75             :   Address fp = *reinterpret_cast<Address*>(*args[0]);
      76             : #elif defined(V8_HOST_ARCH_64_BIT)
      77             :   uint64_t kSmiValueMask =
      78             :       (static_cast<uintptr_t>(1) << (kSmiValueSize - 1)) - 1;
      79             :   uint64_t low_bits =
      80          20 :       Smi(*reinterpret_cast<Address*>(*args[0]))->value() & kSmiValueMask;
      81             :   uint64_t high_bits =
      82          20 :       Smi(*reinterpret_cast<Address*>(*args[1]))->value() & kSmiValueMask;
      83             :   Address fp =
      84          10 :       static_cast<Address>((high_bits << (kSmiValueSize - 1)) | low_bits);
      85             : #else
      86             : #error Host architecture is neither 32-bit nor 64-bit.
      87             : #endif
      88          10 :   printf("Trace: %p\n", reinterpret_cast<void*>(fp));
      89          10 :   return fp;
      90             : }
      91             : 
      92             : static struct { v8::TickSample* sample; } trace_env = {nullptr};
      93             : 
      94          15 : void TraceExtension::InitTraceEnv(v8::TickSample* sample) {
      95          15 :   trace_env.sample = sample;
      96          15 : }
      97             : 
      98             : 
      99          15 : void TraceExtension::DoTrace(Address fp) {
     100             :   RegisterState regs;
     101          15 :   regs.fp = reinterpret_cast<void*>(fp);
     102             :   // sp is only used to define stack high bound
     103             :   regs.sp = reinterpret_cast<void*>(
     104          15 :       reinterpret_cast<Address>(trace_env.sample) - 10240);
     105          15 :   trace_env.sample->Init(CcTest::isolate(), regs,
     106          15 :                          v8::TickSample::kSkipCEntryFrame, true);
     107          15 : }
     108             : 
     109             : 
     110           5 : void TraceExtension::Trace(const v8::FunctionCallbackInfo<v8::Value>& args) {
     111             :   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate());
     112          10 :   i::VMState<EXTERNAL> state(isolate);
     113           5 :   Address address = reinterpret_cast<Address>(&TraceExtension::Trace);
     114          10 :   i::ExternalCallbackScope call_scope(isolate, address);
     115           5 :   DoTrace(GetFP(args));
     116           5 : }
     117             : 
     118             : 
     119             : // Hide c_entry_fp to emulate situation when sampling is done while
     120             : // pure JS code is being executed
     121           5 : static void DoTraceHideCEntryFPAddress(Address fp) {
     122             :   v8::internal::Address saved_c_frame_fp =
     123           5 :       *(CcTest::i_isolate()->c_entry_fp_address());
     124           5 :   CHECK(saved_c_frame_fp);
     125           5 :   *(CcTest::i_isolate()->c_entry_fp_address()) = 0;
     126           5 :   i::TraceExtension::DoTrace(fp);
     127           5 :   *(CcTest::i_isolate()->c_entry_fp_address()) = saved_c_frame_fp;
     128           5 : }
     129             : 
     130             : 
     131           5 : void TraceExtension::JSTrace(const v8::FunctionCallbackInfo<v8::Value>& args) {
     132             :   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate());
     133          10 :   i::VMState<EXTERNAL> state(isolate);
     134           5 :   Address address = reinterpret_cast<Address>(&TraceExtension::JSTrace);
     135          10 :   i::ExternalCallbackScope call_scope(isolate, address);
     136           5 :   DoTraceHideCEntryFPAddress(GetFP(args));
     137           5 : }
     138             : 
     139             : 
     140          40 : Address TraceExtension::GetJsEntrySp() {
     141          40 :   CHECK(CcTest::i_isolate()->thread_local_top());
     142          40 :   return CcTest::i_isolate()->js_entry_sp();
     143             : }
     144             : 
     145             : 
     146          10 : void TraceExtension::JSEntrySP(
     147             :     const v8::FunctionCallbackInfo<v8::Value>& args) {
     148          10 :   CHECK(GetJsEntrySp());
     149          10 : }
     150             : 
     151             : 
     152           5 : void TraceExtension::JSEntrySPLevel2(
     153             :     const v8::FunctionCallbackInfo<v8::Value>& args) {
     154          10 :   v8::HandleScope scope(args.GetIsolate());
     155           5 :   const Address js_entry_sp = GetJsEntrySp();
     156           5 :   CHECK(js_entry_sp);
     157             :   CompileRun("js_entry_sp();");
     158           5 :   CHECK_EQ(js_entry_sp, GetJsEntrySp());
     159           5 : }
     160             : 
     161             : 
     162             : }  // namespace internal
     163       79917 : }  // namespace v8

Generated by: LCOV version 1.10