2 +----------------------------------------------------------------------+
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-2014 Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
17 #include "hphp/runtime/vm/native-data.h"
19 #include "hphp/runtime/base/memory-manager.h"
20 #include "hphp/runtime/base/type-variant.h"
21 #include "hphp/runtime/vm/class.h"
23 namespace HPHP
{ namespace Native
{
24 //////////////////////////////////////////////////////////////////////////////
26 typedef std::unordered_map
<const StringData
*,NativeDataInfo
> NativeDataInfoMap
;
27 static NativeDataInfoMap s_nativedatainfo
;
29 void registerNativeDataInfo(const StringData
* name
,
31 NativeDataInfo::InitFunc init
,
32 NativeDataInfo::CopyFunc copy
,
33 NativeDataInfo::DestroyFunc destroy
,
34 NativeDataInfo::SweepFunc sweep
,
35 NativeDataInfo::SleepFunc sleep
,
36 NativeDataInfo::WakeupFunc wakeup
) {
37 assert(s_nativedatainfo
.find(name
) == s_nativedatainfo
.end());
38 assert((sleep
== nullptr && wakeup
== nullptr) ||
39 (sleep
!= nullptr && wakeup
!= nullptr));
42 info
.odattrs
= ObjectData::Attribute::HasNativeData
;
45 info
.destroy
= destroy
;
49 s_nativedatainfo
[name
] = info
;
52 NativeDataInfo
* getNativeDataInfo(const StringData
* name
) {
53 auto it
= s_nativedatainfo
.find(name
);
54 if (it
== s_nativedatainfo
.end()) {
60 /* Classes with NativeData structs allocate extra memory prior
63 * [NativeNode][padding][NativeData][ObjectData](prop0)...(propN)
65 * ObjectData* points here
67 * padding is added by alignTypedValue(sizeof(NativeData)) to ensure
68 * that ObjectData* falls on a 16-aligned boundary. NativeData is
69 * sizeof(NativeData) (NativeDataInfo.sz) bytes for the custom struct.
70 * NativeNode is a link in the NativeData sweep list for this ND block
72 ObjectData
* nativeDataInstanceCtor(Class
* cls
) {
73 Attr attrs
= cls
->attrs();
75 (AttrAbstract
| AttrInterface
| AttrTrait
| AttrEnum
))) {
76 ObjectData::raiseAbstractClassError(cls
);
78 if (cls
->needInitialization()) {
81 auto ndi
= cls
->getNativeDataInfo();
82 size_t nativeDataSize
= ndsize(ndi
);
83 size_t nProps
= cls
->numDeclProperties();
84 size_t size
= ObjectData::sizeForNProps(nProps
) + nativeDataSize
;
86 auto node
= reinterpret_cast<NativeNode
*>(
87 MM().objMallocLogged(size
)
89 node
->obj_offset
= nativeDataSize
;
90 node
->kind
= HeaderKind::Native
;
91 auto obj
= new (reinterpret_cast<char*>(node
) + nativeDataSize
)
93 obj
->setAttribute(static_cast<ObjectData::Attribute
>(ndi
->odattrs
));
98 MM().addNativeObject(node
);
100 if (UNLIKELY(cls
->callsCustomInstanceInit())) {
101 obj
->callCustomInstanceInit();
103 if (UNLIKELY(cls
->hasNativePropHandler())) {
104 obj
->setAttribute(ObjectData::Attribute::HasNativePropHandler
);
109 void nativeDataInstanceCopy(ObjectData
* dest
, ObjectData
*src
) {
110 auto ndi
= dest
->getVMClass()->getNativeDataInfo();
112 assert(ndi
== src
->getVMClass()->getNativeDataInfo());
114 throw_not_implemented("NativeDataInfoCopy");
116 ndi
->copy(dest
, src
);
117 // Already in the sweep list from init call, no need to add again
120 void nativeDataInstanceDtor(ObjectData
* obj
, const Class
* cls
) {
121 assert(!cls
->preClass()->builtinObjSize());
122 assert(!cls
->preClass()->builtinODOffset());
125 auto const nProps
= size_t{cls
->numDeclProperties()};
126 auto prop
= reinterpret_cast<TypedValue
*>(obj
+ 1);
127 auto const stop
= prop
+ nProps
;
128 for (; prop
!= stop
; ++prop
) {
129 tvRefcountedDecRef(prop
);
132 auto ndi
= cls
->getNativeDataInfo();
136 auto node
= getNativeNode(obj
, ndi
);
138 MM().removeNativeObject(node
);
141 size_t size
= ObjectData::sizeForNProps(nProps
) + ndsize(ndi
);
142 if (LIKELY(size
<= kMaxSmartSize
)) {
143 return MM().smartFreeSizeLogged(node
, size
);
145 MM().smartFreeSizeBigLogged(node
, size
);
148 Variant
nativeDataSleep(const ObjectData
* obj
) {
149 auto ndi
= obj
->getVMClass()->getNativeDataInfo();
152 return ndi
->sleep(obj
);
155 void nativeDataWakeup(ObjectData
* obj
, const Variant
& data
) {
156 auto ndi
= obj
->getVMClass()->getNativeDataInfo();
159 ndi
->wakeup(obj
, data
);
162 //////////////////////////////////////////////////////////////////////////////
163 }} // namespace HPHP::Native