LCOV - code coverage report
Current view: top level - js/src/wasm - WasmCompartment.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 3 55 5.5 %
Date: 2017-07-14 16:53:18 Functions: 1 11 9.1 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
       2             :  * vim: set ts=8 sts=4 et sw=4 tw=99:
       3             :  *
       4             :  * Copyright 2016 Mozilla Foundation
       5             :  *
       6             :  * Licensed under the Apache License, Version 2.0 (the "License");
       7             :  * you may not use this file except in compliance with the License.
       8             :  * You may obtain a copy of the License at
       9             :  *
      10             :  *     http://www.apache.org/licenses/LICENSE-2.0
      11             :  *
      12             :  * Unless required by applicable law or agreed to in writing, software
      13             :  * distributed under the License is distributed on an "AS IS" BASIS,
      14             :  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      15             :  * See the License for the specific language governing permissions and
      16             :  * limitations under the License.
      17             :  */
      18             : 
      19             : #include "wasm/WasmCompartment.h"
      20             : 
      21             : #include "jscompartment.h"
      22             : 
      23             : #include "wasm/WasmInstance.h"
      24             : 
      25             : #include "vm/Debugger-inl.h"
      26             : 
      27             : using namespace js;
      28             : using namespace wasm;
      29             : 
      30             : // With tiering, instances can have one or two code segments, and code that
      31             : // searches the instance list will change.  Search for Tier::TBD below.
      32             : 
      33         315 : Compartment::Compartment(Zone* zone)
      34         315 :   : mutatingInstances_(false)
      35         315 : {}
      36             : 
      37           0 : Compartment::~Compartment()
      38             : {
      39           0 :     MOZ_ASSERT(instances_.empty());
      40           0 :     MOZ_ASSERT(!mutatingInstances_);
      41           0 : }
      42             : 
      43             : struct InstanceComparator
      44             : {
      45             :     const Instance& target;
      46           0 :     explicit InstanceComparator(const Instance& target) : target(target) {}
      47             : 
      48           0 :     int operator()(const Instance* instance) const {
      49           0 :         if (instance == &target)
      50           0 :             return 0;
      51             : 
      52             :         // Instances can share code, so the segments can be equal (though they
      53             :         // can't partially overlap).  If the codeBases are equal, we sort by
      54             :         // Instance address.  Thus a Code may map to many instances.
      55           0 :         if (instance->codeBase(Tier::TBD) == target.codeBase(Tier::TBD))
      56           0 :             return instance < &target ? -1 : 1;
      57             : 
      58           0 :         return target.codeBase(Tier::TBD) < instance->codeBase(Tier::TBD) ? -1 : 1;
      59             :     }
      60             : };
      61             : 
      62             : bool
      63           0 : Compartment::registerInstance(JSContext* cx, HandleWasmInstanceObject instanceObj)
      64             : {
      65           0 :     Instance& instance = instanceObj->instance();
      66           0 :     MOZ_ASSERT(this == &instance.compartment()->wasm);
      67             : 
      68           0 :     instance.ensureProfilingLabels(cx->runtime()->geckoProfiler().enabled());
      69             : 
      70           0 :     if (instance.debugEnabled() &&
      71           0 :         instance.compartment()->debuggerObservesAllExecution())
      72             :     {
      73           0 :         instance.ensureEnterFrameTrapsState(cx, true);
      74             :     }
      75             : 
      76             :     size_t index;
      77           0 :     if (BinarySearchIf(instances_, 0, instances_.length(), InstanceComparator(instance), &index))
      78           0 :         MOZ_CRASH("duplicate registration");
      79             : 
      80             :     {
      81           0 :         AutoMutateInstances guard(*this);
      82           0 :         if (!instances_.insert(instances_.begin() + index, &instance)) {
      83           0 :             ReportOutOfMemory(cx);
      84           0 :             return false;
      85             :         }
      86             :     }
      87             : 
      88           0 :     Debugger::onNewWasmInstance(cx, instanceObj);
      89           0 :     return true;
      90             : }
      91             : 
      92             : void
      93           0 : Compartment::unregisterInstance(Instance& instance)
      94             : {
      95             :     size_t index;
      96           0 :     if (!BinarySearchIf(instances_, 0, instances_.length(), InstanceComparator(instance), &index))
      97           0 :         return;
      98             : 
      99           0 :     AutoMutateInstances guard(*this);
     100           0 :     instances_.erase(instances_.begin() + index);
     101             : }
     102             : 
     103             : struct PCComparator
     104             : {
     105             :     const void* pc;
     106           0 :     explicit PCComparator(const void* pc) : pc(pc) {}
     107             : 
     108           0 :     int operator()(const Instance* instance) const {
     109           0 :         if (instance->codeSegment(Tier::TBD).containsCodePC(pc))
     110           0 :             return 0;
     111           0 :         return pc < instance->codeBase(Tier::TBD) ? -1 : 1;
     112             :     }
     113             : };
     114             : 
     115             : const Code*
     116           0 : Compartment::lookupCode(const void* pc, const CodeSegment** segmentp) const
     117             : {
     118             :     // lookupCode() can be called asynchronously from the interrupt signal
     119             :     // handler. In that case, the signal handler is just asking whether the pc
     120             :     // is in wasm code. If instances_ is being mutated then we can't be
     121             :     // executing wasm code so returning nullptr is fine.
     122           0 :     if (mutatingInstances_)
     123           0 :         return nullptr;
     124             : 
     125             :     size_t index;
     126           0 :     if (!BinarySearchIf(instances_, 0, instances_.length(), PCComparator(pc), &index))
     127           0 :         return nullptr;
     128             : 
     129           0 :     const Code& code = instances_[index]->code();
     130           0 :     if (segmentp)
     131           0 :         *segmentp = &code.segment(Tier::TBD);
     132           0 :     return &code;
     133             : }
     134             : 
     135             : void
     136           0 : Compartment::ensureProfilingLabels(bool profilingEnabled)
     137             : {
     138           0 :     for (Instance* instance : instances_)
     139           0 :         instance->ensureProfilingLabels(profilingEnabled);
     140           0 : }
     141             : 
     142             : void
     143           0 : Compartment::addSizeOfExcludingThis(MallocSizeOf mallocSizeOf, size_t* compartmentTables)
     144             : {
     145           0 :     *compartmentTables += instances_.sizeOfExcludingThis(mallocSizeOf);
     146           0 : }

Generated by: LCOV version 1.13