/ b3 / B3MemoryValue.cpp
B3MemoryValue.cpp
  1  /*
  2   * Copyright (C) 2015-2017 Apple Inc. All rights reserved.
  3   *
  4   * Redistribution and use in source and binary forms, with or without
  5   * modification, are permitted provided that the following conditions
  6   * are met:
  7   * 1. Redistributions of source code must retain the above copyright
  8   *    notice, this list of conditions and the following disclaimer.
  9   * 2. Redistributions in binary form must reproduce the above copyright
 10   *    notice, this list of conditions and the following disclaimer in the
 11   *    documentation and/or other materials provided with the distribution.
 12   *
 13   * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 14   * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 15   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16   * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 17   * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 18   * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 19   * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 20   * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 21   * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 23   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 24   */
 25  
 26  #include "config.h"
 27  #include "B3MemoryValue.h"
 28  
 29  #if ENABLE(B3_JIT)
 30  
 31  #include "B3MemoryValueInlines.h"
 32  #include "B3ValueInlines.h"
 33  
 34  namespace JSC { namespace B3 {
 35  
 36  MemoryValue::~MemoryValue()
 37  {
 38  }
 39  
 40  bool MemoryValue::isLegalOffsetImpl(int64_t offset) const
 41  {
 42      return B3::isRepresentableAs<OffsetType>(offset) && isLegalOffset(static_cast<OffsetType>(offset));
 43  }
 44  
 45  Type MemoryValue::accessType() const
 46  {
 47      if (isLoad())
 48          return type();
 49      // This happens to work for atomics, too. That's why AtomicValue does not need to override this.
 50      return child(0)->type();
 51  }
 52  
 53  Bank MemoryValue::accessBank() const
 54  {
 55      return bankForType(accessType());
 56  }
 57  
 58  size_t MemoryValue::accessByteSize() const
 59  {
 60      return bytes(accessWidth());
 61  }
 62  
 63  void MemoryValue::dumpMeta(CommaPrinter& comma, PrintStream& out) const
 64  {
 65      if (m_offset)
 66          out.print(comma, "offset = ", m_offset);
 67      if ((isLoad() && effects().reads != range())
 68          || (isStore() && effects().writes != range())
 69          || isExotic())
 70          out.print(comma, "range = ", range());
 71      if (isExotic())
 72          out.print(comma, "fenceRange = ", fenceRange());
 73  }
 74  
 75  // Use this form for Load (but not Load8Z, Load8S, or any of the Loads that have a suffix that
 76  // describes the returned type).
 77  MemoryValue::MemoryValue(MemoryValue::MemoryValueLoad, Kind kind, Type type, Origin origin, Value* pointer, MemoryValue::OffsetType offset, HeapRange range, HeapRange fenceRange)
 78      : Value(CheckedOpcode, kind, type, One, origin, pointer)
 79      , m_offset(offset)
 80      , m_range(range)
 81      , m_fenceRange(fenceRange)
 82  {
 83      if (ASSERT_ENABLED) {
 84          switch (kind.opcode()) {
 85          case Load:
 86              break;
 87          case Load8Z:
 88          case Load8S:
 89          case Load16Z:
 90          case Load16S:
 91              ASSERT(type == Int32);
 92              break;
 93          case Store8:
 94          case Store16:
 95          case Store:
 96              ASSERT(type == Void);
 97              break;
 98          default:
 99              ASSERT_NOT_REACHED();
100          }
101      }
102  }
103  
104  // Use this form for loads where the return type is implied.
105  MemoryValue::MemoryValue(MemoryValue::MemoryValueLoadImplied, Kind kind, Origin origin, Value* pointer, MemoryValue::OffsetType offset, HeapRange range, HeapRange fenceRange)
106      : MemoryValue(kind, Int32, origin, pointer, offset, range, fenceRange)
107  {
108      if (ASSERT_ENABLED) {
109          switch (kind.opcode()) {
110          case Load8Z:
111          case Load8S:
112          case Load16Z:
113          case Load16S:
114              break;
115          default:
116              ASSERT_NOT_REACHED();
117          }
118      }
119  }
120  
121  // Use this form for stores.
122  MemoryValue::MemoryValue(MemoryValue::MemoryValueStore, Kind kind, Origin origin, Value* value, Value* pointer, MemoryValue::OffsetType offset, HeapRange range, HeapRange fenceRange)
123      : Value(CheckedOpcode, kind, Void, Two, origin, value, pointer)
124      , m_offset(offset)
125      , m_range(range)
126      , m_fenceRange(fenceRange)
127  {
128      ASSERT(B3::isStore(kind.opcode()));
129  }
130  
131  } } // namespace JSC::B3
132  
133  #endif // ENABLE(B3_JIT)