/ bytecode / ObjectAllocationProfile.h
ObjectAllocationProfile.h
  1  /*
  2   * Copyright (C) 2013-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  #pragma once
 27  
 28  #include "VM.h"
 29  #include "JSGlobalObject.h"
 30  #include "ObjectPrototype.h"
 31  #include "SlotVisitor.h"
 32  #include "WriteBarrier.h"
 33  
 34  namespace JSC {
 35  
 36  class FunctionRareData;
 37  
 38  template<typename Derived>
 39  class ObjectAllocationProfileBase {
 40      friend class LLIntOffsetsExtractor;
 41  public:
 42      static ptrdiff_t offsetOfAllocator() { return OBJECT_OFFSETOF(ObjectAllocationProfileBase, m_allocator); }
 43      static ptrdiff_t offsetOfStructure() { return OBJECT_OFFSETOF(ObjectAllocationProfileBase, m_structure); }
 44  
 45      ObjectAllocationProfileBase() = default;
 46  
 47      bool isNull() { return !m_structure; }
 48  
 49      void initializeProfile(VM&, JSGlobalObject*, JSCell* owner, JSObject* prototype, unsigned inferredInlineCapacity, JSFunction* constructor = nullptr, FunctionRareData* = nullptr);
 50  
 51      Structure* structure()
 52      {
 53          Structure* structure = m_structure.get();
 54          // Ensure that if we see the structure, it has been properly created
 55          WTF::loadLoadFence();
 56          return structure;
 57      }
 58  
 59  protected:
 60      void clear()
 61      {
 62          m_allocator = Allocator();
 63          m_structure.clear();
 64          ASSERT(isNull());
 65      }
 66  
 67      void visitAggregate(SlotVisitor& visitor)
 68      {
 69          visitor.append(m_structure);
 70      }
 71  
 72  private:
 73      unsigned possibleDefaultPropertyCount(VM&, JSObject* prototype);
 74  
 75      Allocator m_allocator; // Precomputed to make things easier for generated code.
 76      WriteBarrier<Structure> m_structure;
 77  };
 78  
 79  class ObjectAllocationProfile : public ObjectAllocationProfileBase<ObjectAllocationProfile> {
 80  public:
 81      using Base = ObjectAllocationProfileBase<ObjectAllocationProfile>;
 82  
 83      ObjectAllocationProfile() = default;
 84  
 85      using Base::clear;
 86      using Base::visitAggregate;
 87  
 88      void setPrototype(VM&, JSCell*, JSObject*) { }
 89  };
 90  
 91  class ObjectAllocationProfileWithPrototype : public ObjectAllocationProfileBase<ObjectAllocationProfileWithPrototype> {
 92  public:
 93      using Base = ObjectAllocationProfileBase<ObjectAllocationProfileWithPrototype>;
 94  
 95      static ptrdiff_t offsetOfPrototype() { return OBJECT_OFFSETOF(ObjectAllocationProfileWithPrototype, m_prototype); }
 96  
 97      ObjectAllocationProfileWithPrototype() = default;
 98  
 99      JSObject* prototype()
100      {
101          JSObject* prototype = m_prototype.get();
102          WTF::loadLoadFence();
103          return prototype;
104      }
105  
106      void clear()
107      {
108          Base::clear();
109          m_prototype.clear();
110          ASSERT(isNull());
111      }
112  
113      void visitAggregate(SlotVisitor& visitor)
114      {
115          Base::visitAggregate(visitor);
116          visitor.append(m_prototype);
117      }
118  
119      void setPrototype(VM& vm, JSCell* owner, JSObject* object)
120      {
121          m_prototype.set(vm, owner, object);
122      }
123  
124  private:
125      WriteBarrier<JSObject> m_prototype;
126  };
127  
128  
129  
130  } // namespace JSC