LCOV - code coverage report
Current view: top level - src/ic - handler-compiler.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 44 44 100.0 %
Date: 2017-04-26 Functions: 8 8 100.0 %

          Line data    Source code
       1             : // Copyright 2014 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #include "src/ic/handler-compiler.h"
       6             : 
       7             : #include "src/assembler-inl.h"
       8             : #include "src/field-type.h"
       9             : #include "src/ic/call-optimization.h"
      10             : #include "src/ic/handler-configuration-inl.h"
      11             : #include "src/ic/ic-inl.h"
      12             : #include "src/ic/ic.h"
      13             : #include "src/isolate-inl.h"
      14             : 
      15             : namespace v8 {
      16             : namespace internal {
      17             : 
      18       41492 : Handle<Code> PropertyHandlerCompiler::Find(Handle<Name> name,
      19             :                                            Handle<Map> stub_holder,
      20             :                                            Code::Kind kind) {
      21             :   Code::Flags flags = Code::ComputeHandlerFlags(kind);
      22       41492 :   Code* code = stub_holder->LookupInCodeCache(*name, flags);
      23       41492 :   if (code == nullptr) return Handle<Code>();
      24             :   return handle(code);
      25             : }
      26             : 
      27       38698 : Handle<Code> PropertyHandlerCompiler::GetCode(Code::Kind kind,
      28             :                                               Handle<Name> name) {
      29             :   Code::Flags flags = Code::ComputeHandlerFlags(kind);
      30             : 
      31             :   // Create code object in the heap.
      32             :   CodeDesc desc;
      33       77396 :   masm()->GetCode(&desc);
      34       38698 :   Handle<Code> code = factory()->NewCode(desc, flags, masm()->CodeObject());
      35       38698 :   if (code->IsCodeStubOrIC()) code->set_stub_key(CodeStub::NoCacheKey());
      36             : #ifdef ENABLE_DISASSEMBLER
      37             :   if (FLAG_print_code_stubs) {
      38             :     char* raw_name = !name.is_null() && name->IsString()
      39             :                          ? String::cast(*name)->ToCString().get()
      40             :                          : nullptr;
      41             :     CodeTracer::Scope trace_scope(isolate()->GetCodeTracer());
      42             :     OFStream os(trace_scope.file());
      43             :     code->Disassemble(raw_name, os);
      44             :   }
      45             : #endif
      46             : 
      47       38698 :   PROFILE(isolate(), CodeCreateEvent(CodeEventListener::HANDLER_TAG,
      48             :                                      AbstractCode::cast(*code), *name));
      49             : 
      50             : #ifdef DEBUG
      51             :   code->VerifyEmbeddedObjects();
      52             : #endif
      53       38698 :   return code;
      54             : }
      55             : 
      56             : 
      57             : #define __ ACCESS_MASM(masm())
      58             : 
      59         277 : Register NamedLoadHandlerCompiler::FrontendHeader(Register object_reg,
      60             :                                                   Handle<Name> name,
      61         277 :                                                   Label* miss) {
      62         554 :   if (map()->IsPrimitiveMap() || map()->IsJSGlobalProxyMap()) {
      63             :     // If the receiver is a global proxy and if we get to this point then
      64             :     // the compile-time (current) native context has access to global proxy's
      65             :     // native context. Since access rights revocation is not supported at all,
      66             :     // we can generate a check that an execution-time native context is either
      67             :     // the same as compile-time native context or has the same access token.
      68          12 :     Handle<Context> native_context = isolate()->native_context();
      69             :     Handle<WeakCell> weak_cell(native_context->self_weak_cell(), isolate());
      70             : 
      71             :     bool compare_native_contexts_only = map()->IsPrimitiveMap();
      72             :     GenerateAccessCheck(weak_cell, scratch1(), scratch2(), miss,
      73          12 :                         compare_native_contexts_only);
      74             :   }
      75             : 
      76             :   // Check that the maps starting from the prototype haven't changed.
      77             :   return CheckPrototypes(object_reg, scratch1(), scratch2(), scratch3(), name,
      78         277 :                          miss);
      79             : }
      80             : 
      81             : 
      82             : // Frontend for store uses the name register. It has to be restored before a
      83             : // miss.
      84       38421 : Register NamedStoreHandlerCompiler::FrontendHeader(Register object_reg,
      85             :                                                    Handle<Name> name,
      86             :                                                    Label* miss) {
      87       38421 :   if (map()->IsJSGlobalProxyMap()) {
      88       38573 :     Handle<Context> native_context = isolate()->native_context();
      89             :     Handle<WeakCell> weak_cell(native_context->self_weak_cell(), isolate());
      90          76 :     GenerateAccessCheck(weak_cell, scratch1(), scratch2(), miss, false);
      91             :   }
      92             : 
      93             :   return CheckPrototypes(object_reg, this->name(), scratch1(), scratch2(), name,
      94       38421 :                          miss);
      95             : }
      96             : 
      97             : 
      98       38698 : Register PropertyHandlerCompiler::Frontend(Handle<Name> name) {
      99             :   Label miss;
     100      116094 :   if (IC::ShouldPushPopSlotAndVector(kind())) {
     101       38698 :     PushVectorAndSlot();
     102             :   }
     103       77396 :   Register reg = FrontendHeader(receiver(), name, &miss);
     104       38698 :   FrontendFooter(name, &miss);
     105             :   // The footer consumes the vector and slot from the stack if miss occurs.
     106       38698 :   if (IC::ShouldPushPopSlotAndVector(kind())) {
     107       38698 :     DiscardVectorAndSlot();
     108             :   }
     109       38698 :   return reg;
     110             : }
     111             : 
     112         277 : Handle<Code> NamedLoadHandlerCompiler::CompileLoadCallback(
     113             :     Handle<Name> name, const CallOptimization& call_optimization,
     114             :     int accessor_index, Handle<Code> slow_stub) {
     115             :   DCHECK(call_optimization.is_simple_api_call());
     116         277 :   if (V8_UNLIKELY(FLAG_runtime_stats)) {
     117         554 :     GenerateTailCall(masm(), slow_stub);
     118             :   }
     119         277 :   Register holder = Frontend(name);
     120             :   GenerateApiAccessorCall(masm(), call_optimization, map(), receiver(),
     121         277 :                           scratch2(), false, no_reg, holder, accessor_index);
     122         277 :   return GetCode(kind(), name);
     123             : }
     124             : 
     125       18064 : Handle<Code> NamedStoreHandlerCompiler::CompileStoreViaSetter(
     126             :     Handle<JSObject> object, Handle<Name> name, int accessor_index,
     127             :     int expected_arguments) {
     128       18064 :   Register holder = Frontend(name);
     129             :   GenerateStoreViaSetter(masm(), map(), receiver(), holder, accessor_index,
     130       36128 :                          expected_arguments, scratch2());
     131             : 
     132       18064 :   return GetCode(kind(), name);
     133             : }
     134             : 
     135          70 : Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
     136             :     Handle<JSObject> object, Handle<Name> name,
     137             :     const CallOptimization& call_optimization, int accessor_index,
     138             :     Handle<Code> slow_stub) {
     139          70 :   if (V8_UNLIKELY(FLAG_runtime_stats)) {
     140         140 :     GenerateTailCall(masm(), slow_stub);
     141             :   }
     142          70 :   Register holder = Frontend(name);
     143             :   if (Descriptor::kPassLastArgsOnStack) {
     144             :     __ LoadParameterFromStack<Descriptor>(value(), Descriptor::kValue);
     145             :   }
     146             :   GenerateApiAccessorCall(masm(), call_optimization, handle(object->map()),
     147             :                           receiver(), scratch2(), true, value(), holder,
     148         140 :                           accessor_index);
     149          70 :   return GetCode(kind(), name);
     150             : }
     151             : 
     152             : 
     153             : #undef __
     154             : 
     155             : }  // namespace internal
     156             : }  // namespace v8

Generated by: LCOV version 1.10