LCOV - code coverage report
Current view: top level - js/src/jit - Label.h (source / functions) Hit Total Coverage
Test: output.info Lines: 39 39 100.0 %
Date: 2017-07-14 16:53:18 Functions: 11 11 100.0 %
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             :  * This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #ifndef jit_Label_h
       8             : #define jit_Label_h
       9             : 
      10             : #include "jit/Ion.h"
      11             : 
      12             : namespace js {
      13             : namespace jit {
      14             : 
      15             : struct LabelBase
      16             : {
      17             :   protected:
      18             :     // offset_ >= 0 means that the label is either bound or has incoming
      19             :     // uses and needs to be bound.
      20             :     int32_t offset_ : 31;
      21             :     bool bound_   : 1;
      22             : 
      23             :     void operator =(const LabelBase& label) = delete;
      24             : 
      25             :   public:
      26             :     static const int32_t INVALID_OFFSET = -1;
      27             : 
      28      225218 :     LabelBase() : offset_(INVALID_OFFSET), bound_(false)
      29      225218 :     { }
      30             : 
      31             :     // If the label is bound, all incoming edges have been patched and any
      32             :     // future incoming edges will be immediately patched.
      33      480464 :     bool bound() const {
      34      480464 :         return bound_;
      35             :     }
      36       42099 :     int32_t offset() const {
      37       42099 :         MOZ_ASSERT(bound() || used());
      38       42098 :         return offset_;
      39             :     }
      40             :     void offsetBy(int32_t delta) {
      41             :         MOZ_ASSERT(bound() || used());
      42             :         MOZ_ASSERT(offset() + delta >= offset(), "no overflow");
      43             :         mozilla::DebugOnly<int32_t> oldOffset(offset());
      44             :         offset_ += delta;
      45             :         MOZ_ASSERT(offset_ == delta + oldOffset, "new offset fits in 31 bits");
      46             :     }
      47             :     // Returns whether the label is not bound, but has incoming uses.
      48      227124 :     bool used() const {
      49      227124 :         return !bound() && offset_ > INVALID_OFFSET;
      50             :     }
      51             :     // Binds the label, fixing its final position in the code stream.
      52      114025 :     void bind(int32_t offset) {
      53      114025 :         MOZ_ASSERT(!bound());
      54      114026 :         offset_ = offset;
      55      114026 :         bound_ = true;
      56      114026 :         MOZ_ASSERT(offset_ == offset, "offset fits in 31 bits");
      57      114026 :     }
      58             :     // Marks the label as neither bound nor used.
      59         279 :     void reset() {
      60         279 :         offset_ = INVALID_OFFSET;
      61         279 :         bound_ = false;
      62         279 :     }
      63             :     // Sets the label's latest used position, returning the old use position in
      64             :     // the process.
      65       47631 :     int32_t use(int32_t offset) {
      66       47631 :         MOZ_ASSERT(!bound());
      67             : 
      68       47631 :         int32_t old = offset_;
      69       47631 :         offset_ = offset;
      70       47631 :         MOZ_ASSERT(offset_ == offset, "offset fits in 31 bits");
      71             : 
      72       47631 :         return old;
      73             :     }
      74             : };
      75             : 
      76             : // A label represents a position in an assembly buffer that may or may not have
      77             : // already been generated. Labels can either be "bound" or "unbound", the
      78             : // former meaning that its position is known and the latter that its position
      79             : // is not yet known.
      80             : //
      81             : // A jump to an unbound label adds that jump to the label's incoming queue. A
      82             : // jump to a bound label automatically computes the jump distance. The process
      83             : // of binding a label automatically corrects all incoming jumps.
      84      225218 : class Label : public LabelBase
      85             : {
      86             :   public:
      87       59747 :     ~Label()
      88       59747 :     {
      89             : #ifdef DEBUG
      90             :         // The assertion below doesn't hold if an error occurred.
      91       59747 :         JitContext* context = MaybeGetJitContext();
      92       59747 :         bool hadError = js::oom::HadSimulatedOOM() ||
      93      119462 :                         (context && context->runtime && context->runtime->hadOutOfMemory());
      94       59747 :         MOZ_ASSERT_IF(!hadError, !used());
      95             : #endif
      96       59747 :     }
      97             : };
      98             : 
      99             : // Label's destructor asserts that if it has been used it has also been bound.
     100             : // In the case long-lived labels, however, failed compilation (e.g. OOM) will
     101             : // trigger this failure innocuously. This Label silences the assertion.
     102        6742 : class NonAssertingLabel : public Label
     103             : {
     104             :   public:
     105        7321 :     ~NonAssertingLabel()
     106        7321 :     {
     107             : #ifdef DEBUG
     108        7321 :         if (used())
     109           1 :             bind(0);
     110             : #endif
     111        7321 :     }
     112             : };
     113             : 
     114             : } // namespace jit
     115             : } // namespace js
     116             : 
     117             : #endif // jit_Label_h

Generated by: LCOV version 1.13