LCOV - code coverage report
Current view: top level - src/ic - handler-compiler.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 40 41 97.6 %
Date: 2017-10-20 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      245699 : Handle<Code> PropertyHandlerCompiler::GetCode(Handle<Name> name) {
      19             :   // Create code object in the heap.
      20             :   CodeDesc desc;
      21      491398 :   masm()->GetCode(isolate(), &desc);
      22             :   Handle<Code> code =
      23      245699 :       factory()->NewCode(desc, Code::STUB, masm()->CodeObject());
      24             :   DCHECK(code->is_stub());
      25             :   code->set_stub_key(CodeStub::NoCacheKey());
      26             : #ifdef ENABLE_DISASSEMBLER
      27             :   if (FLAG_print_code_stubs) {
      28             :     char* raw_name = !name.is_null() && name->IsString()
      29             :                          ? String::cast(*name)->ToCString().get()
      30             :                          : nullptr;
      31             :     CodeTracer::Scope trace_scope(isolate()->GetCodeTracer());
      32             :     OFStream os(trace_scope.file());
      33             :     code->Disassemble(raw_name, os);
      34             :   }
      35             : #endif
      36             : 
      37      245699 :   PROFILE(isolate(), CodeCreateEvent(CodeEventListener::HANDLER_TAG,
      38             :                                      AbstractCode::cast(*code), *name));
      39             : 
      40             : #ifdef DEBUG
      41             :   code->VerifyEmbeddedObjects();
      42             : #endif
      43      245699 :   return code;
      44             : }
      45             : 
      46             : 
      47             : #define __ ACCESS_MASM(masm())
      48             : 
      49        3512 : Register NamedLoadHandlerCompiler::FrontendHeader(Register object_reg,
      50             :                                                   Handle<Name> name,
      51        3512 :                                                   Label* miss) {
      52        3512 :   if (map()->IsPrimitiveMap() || map()->IsJSGlobalProxyMap()) {
      53             :     // If the receiver is a global proxy and if we get to this point then
      54             :     // the compile-time (current) native context has access to global proxy's
      55             :     // native context. Since access rights revocation is not supported at all,
      56             :     // we can generate a check that an execution-time native context is either
      57             :     // the same as compile-time native context or has the same access token.
      58          10 :     Handle<Context> native_context = isolate()->native_context();
      59             :     Handle<WeakCell> weak_cell(native_context->self_weak_cell(), isolate());
      60             : 
      61             :     bool compare_native_contexts_only = map()->IsPrimitiveMap();
      62             :     GenerateAccessCheck(weak_cell, scratch1(), scratch2(), miss,
      63          10 :                         compare_native_contexts_only);
      64             :   }
      65             : 
      66             :   // Check that the maps starting from the prototype haven't changed.
      67             :   return CheckPrototypes(object_reg, scratch1(), scratch2(), scratch3(), name,
      68        3512 :                          miss);
      69             : }
      70             : 
      71             : 
      72             : // Frontend for store uses the name register. It has to be restored before a
      73             : // miss.
      74      242187 : Register NamedStoreHandlerCompiler::FrontendHeader(Register object_reg,
      75             :                                                    Handle<Name> name,
      76             :                                                    Label* miss) {
      77      242187 :   if (map()->IsJSGlobalProxyMap()) {
      78      242323 :     Handle<Context> native_context = isolate()->native_context();
      79             :     Handle<WeakCell> weak_cell(native_context->self_weak_cell(), isolate());
      80          68 :     GenerateAccessCheck(weak_cell, scratch1(), scratch2(), miss, false);
      81             :   }
      82             : 
      83             :   return CheckPrototypes(object_reg, this->name(), scratch1(), scratch2(), name,
      84      242187 :                          miss);
      85             : }
      86             : 
      87             : // The ICs that don't pass slot and vector through the stack have to
      88             : // save/restore them in the dispatcher.
      89      491398 : bool PropertyHandlerCompiler::ShouldPushPopSlotAndVector() {
      90      491398 :   switch (type()) {
      91             :     case LOAD:
      92             :       return true;
      93             :     case STORE:
      94             :       return !StoreWithVectorDescriptor::kPassLastArgsOnStack;
      95             :   }
      96           0 :   UNREACHABLE();
      97             :   return false;
      98             : }
      99             : 
     100      245699 : Register PropertyHandlerCompiler::Frontend(Handle<Name> name) {
     101             :   Label miss;
     102      245699 :   if (ShouldPushPopSlotAndVector()) PushVectorAndSlot();
     103      491398 :   Register reg = FrontendHeader(receiver(), name, &miss);
     104      245699 :   FrontendFooter(name, &miss);
     105             :   // The footer consumes the vector and slot from the stack if miss occurs.
     106      245699 :   if (ShouldPushPopSlotAndVector()) DiscardVectorAndSlot();
     107      245699 :   return reg;
     108             : }
     109             : 
     110        3512 : Handle<Code> NamedLoadHandlerCompiler::CompileLoadCallback(
     111             :     Handle<Name> name, const CallOptimization& call_optimization,
     112             :     int accessor_index, Handle<Code> slow_stub) {
     113             :   DCHECK(call_optimization.is_simple_api_call());
     114        3512 :   if (V8_UNLIKELY(FLAG_runtime_stats)) {
     115        3512 :     GenerateTailCall(masm(), slow_stub);
     116             :   }
     117        3512 :   Register holder = Frontend(name);
     118             :   GenerateApiAccessorCall(masm(), call_optimization, map(), receiver(),
     119        3512 :                           scratch2(), false, no_reg, holder, accessor_index);
     120        3512 :   return GetCode(name);
     121             : }
     122             : 
     123      141317 : Handle<Code> NamedStoreHandlerCompiler::CompileStoreViaSetter(
     124             :     Handle<JSObject> object, Handle<Name> name, int accessor_index,
     125             :     int expected_arguments) {
     126      141317 :   Register holder = Frontend(name);
     127             :   GenerateStoreViaSetter(masm(), map(), receiver(), holder, accessor_index,
     128      282634 :                          expected_arguments, scratch2());
     129             : 
     130      141317 :   return GetCode(name);
     131             : }
     132             : 
     133         274 : Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
     134             :     Handle<JSObject> object, Handle<Name> name,
     135             :     const CallOptimization& call_optimization, int accessor_index,
     136             :     Handle<Code> slow_stub) {
     137         274 :   if (V8_UNLIKELY(FLAG_runtime_stats)) {
     138         274 :     GenerateTailCall(masm(), slow_stub);
     139             :   }
     140         274 :   Register holder = Frontend(name);
     141             :   if (Descriptor::kPassLastArgsOnStack) {
     142             :     __ LoadParameterFromStack<Descriptor>(value(), Descriptor::kValue);
     143             :   }
     144             :   GenerateApiAccessorCall(masm(), call_optimization, handle(object->map()),
     145             :                           receiver(), scratch2(), true, value(), holder,
     146         548 :                           accessor_index);
     147         274 :   return GetCode(name);
     148             : }
     149             : 
     150             : 
     151             : #undef __
     152             : 
     153             : }  // namespace internal
     154             : }  // namespace v8

Generated by: LCOV version 1.10