示例#1
0
void nativeDataInstanceDtor(ObjectData* obj, const Class* cls) {
  assert(!cls->preClass()->builtinObjSize());
  assert(!cls->preClass()->builtinODOffset());
  obj->~ObjectData();

  auto const nProps = size_t{cls->numDeclProperties()};
  auto prop = reinterpret_cast<TypedValue*>(obj + 1);
  auto const stop = prop + nProps;
  for (; prop != stop; ++prop) {
    tvRefcountedDecRef(prop);
  }

  auto ndi = cls->getNativeDataInfo();
  if (ndi->destroy) {
    ndi->destroy(obj);
  }
  auto node = getNativeNode(obj, ndi);
  if (ndi->sweep) {
    MM().removeNativeObject(node);
  }

  size_t size = ObjectData::sizeForNProps(nProps) + ndsize(obj, ndi);
  if (LIKELY(size <= kMaxSmallSize)) {
    return MM().freeSmallSize(node, size);
  }
  MM().freeBigSize(node, size);
}
示例#2
0
/* Classes with NativeData structs allocate extra memory prior
 * to the ObjectData.
 *
 * [NativeNode][padding][NativeData][ObjectData](prop0)...(propN)
 *                                 /\
 *                             ObjectData* points here
 *
 * padding is added by alignTypedValue(sizeof(NativeData)) to ensure
 * that ObjectData* falls on a 16-aligned boundary. NativeData is
 * sizeof(NativeData) (NativeDataInfo.sz) bytes for the custom struct.
 * NativeNode is a link in the NativeData sweep list for this ND block
 */
ObjectData* nativeDataInstanceCtor(Class* cls) {
  HPHP::Attr attrs = cls->attrs();
  if (UNLIKELY(attrs &
               (AttrAbstract | AttrInterface | AttrTrait | AttrEnum))) {
    ObjectData::raiseAbstractClassError(cls);
  }
  auto ndi = cls->getNativeDataInfo();
  size_t nativeDataSize = ndsize(ndi->sz);
  size_t nProps = cls->numDeclProperties();
  size_t size = ObjectData::sizeForNProps(nProps) + nativeDataSize;

  auto node = reinterpret_cast<NativeNode*>(
    MM().objMalloc(size)
  );
  node->obj_offset = nativeDataSize;
  node->hdr.kind = HeaderKind::NativeData;
  auto obj = new (reinterpret_cast<char*>(node) + nativeDataSize)
             ObjectData(cls);
  assert(obj->hasExactlyOneRef());
  obj->setAttribute(static_cast<ObjectData::Attribute>(ndi->odattrs));
  if (ndi->init) {
    ndi->init(obj);
  }
  if (ndi->sweep) {
    MM().addNativeObject(node);
  }
  if (UNLIKELY(cls->needsInitThrowable())) {
    obj->callCustomInstanceInit();
  }
  return obj;
}
示例#3
0
size_t ndsize(const ObjectData* obj, const NativeDataInfo* ndi) {
  auto cls = obj->getVMClass();
  if (cls == Generator::getClass() || cls == AsyncGenerator::getClass()) {
    return (cls == Generator::getClass())
      ? Native::data<Generator>(obj)->resumable()->size()
      - sizeof(ObjectData)
      : Native::data<AsyncGenerator>(obj)->resumable()->size()
      - sizeof(ObjectData);
  }
  return ndsize(ndi->sz);
}
示例#4
0
void sweepNativeData(std::vector<NativeNode*>& natives) {
  while (!natives.empty()) {
    assert(natives.back()->sweep_index == natives.size() - 1);
    auto node = natives.back();
    natives.pop_back();
    auto obj = Native::obj(node);
    auto ndi = obj->getVMClass()->getNativeDataInfo();
    assert(ndi->sweep);
    assert(node->obj_offset == ndsize(ndi));
    ndi->sweep(obj);
    assert(invalidateNativeData(obj, ndi));
  }
}
示例#5
0
/* Classes with NativeData structs allocate extra memory prior
 * to the ObjectData.
 *
 * [NativeNode][padding][NativeData][ObjectData](prop0)...(propN)
 *                                 /\
 *                             ObjectData* points here
 *
 * padding is added by alignTypedValue(sizeof(NativeData)) to ensure
 * that ObjectData* falls on a 16-aligned boundary. NativeData is
 * sizeof(NativeData) (NativeDataInfo.sz) bytes for the custom struct.
 * NativeNode is a link in the NativeData sweep list for this ND block
 */
ObjectData* nativeDataInstanceCtor(Class* cls) {
  auto ndi = cls->getNativeDataInfo();
  size_t nativeDataSize = ndsize(ndi->sz);
  size_t nProps = cls->numDeclProperties();
  size_t size = ObjectData::sizeForNProps(nProps) + nativeDataSize;

  auto node = reinterpret_cast<NativeNode*>(
    MM().objMalloc(size)
  );
  node->obj_offset = nativeDataSize;
  node->hdr.kind = HeaderKind::NativeData;
  auto obj = new (reinterpret_cast<char*>(node) + nativeDataSize)
             ObjectData(cls);
  assert(obj->hasExactlyOneRef());
  obj->setAttribute(static_cast<ObjectData::Attribute>(ndi->odattrs));
  if (ndi->init) {
    ndi->init(obj);
  }
  if (ndi->sweep) {
    MM().addNativeObject(node);
  }
  return obj;
}
示例#6
0
DEBUG_ONLY
static bool invalidateNativeData(ObjectData* obj, const NativeDataInfo* ndi) {
  memset(getSweepNode(obj, ndi), kSmartFreeFill, ndsize(ndi));
  return true;
}
示例#7
0
inline NativeNode* getSweepNode(ObjectData *obj, const NativeDataInfo* ndi) {
  return reinterpret_cast<NativeNode*>(
    reinterpret_cast<char*>(obj) - ndsize(ndi)
  );
}