Rename RefcountProfile to IncRefProfile
[hiphop-php.git] / hphp / runtime / vm / jit / irlower-collection.cpp
bloba37930e62e964396958199a5923b09751dcea62f
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-present 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/jit/irlower-internal.h"
19 #include "hphp/runtime/base/collections.h"
20 #include "hphp/runtime/base/object-data.h"
21 #include "hphp/runtime/base/packed-array.h"
23 #include "hphp/runtime/ext/collections/ext_collections.h"
24 #include "hphp/runtime/ext/collections/ext_collections-pair.h"
25 #include "hphp/runtime/ext/collections/ext_collections-vector.h"
26 #include "hphp/runtime/ext/collections/hash-collection.h"
28 #include "hphp/runtime/vm/jit/types.h"
29 #include "hphp/runtime/vm/jit/call-spec.h"
30 #include "hphp/runtime/vm/jit/code-gen-cf.h"
31 #include "hphp/runtime/vm/jit/code-gen-helpers.h"
32 #include "hphp/runtime/vm/jit/extra-data.h"
33 #include "hphp/runtime/vm/jit/ir-instruction.h"
34 #include "hphp/runtime/vm/jit/ir-opcode.h"
35 #include "hphp/runtime/vm/jit/ssa-tmp.h"
36 #include "hphp/runtime/vm/jit/type.h"
37 #include "hphp/runtime/vm/jit/type-specialization.h"
38 #include "hphp/runtime/vm/jit/vasm-gen.h"
39 #include "hphp/runtime/vm/jit/vasm-instr.h"
40 #include "hphp/runtime/vm/jit/vasm-reg.h"
42 #include "hphp/util/asm-x64.h"
43 #include "hphp/util/trace.h"
45 namespace HPHP { namespace jit { namespace irlower {
47 TRACE_SET_MOD(irlower);
49 ///////////////////////////////////////////////////////////////////////////////
51 namespace {
53 void implColTestSize(IRLS& env, const IRInstruction* inst, ConditionCode cc) {
54 DEBUG_ONLY auto const ty = inst->src(0)->type();
55 assertx(ty < TObj &&
56 ty.clsSpec().cls() &&
57 ty.clsSpec().cls()->isCollectionClass());
59 auto const dst = dstLoc(env, inst, 0).reg();
60 auto const src = srcLoc(env, inst, 0).reg();
61 auto& v = vmain(env);
63 auto const sf = v.makeReg();
64 v << cmplim{0, src[collections::FAST_SIZE_OFFSET], sf};
65 v << setcc{cc, sf, dst};
70 void cgIsCol(IRLS& env, const IRInstruction* inst) {
71 assertx(inst->src(0)->type() <= TObj);
73 auto const dst = dstLoc(env, inst, 0).reg();
74 auto const src = srcLoc(env, inst, 0).reg();
75 auto& v = vmain(env);
77 auto const sf = emitIsCollection(v, src);
78 v << setcc{CC_BE, sf, dst};
81 void cgColIsEmpty(IRLS& env, const IRInstruction* inst) {
82 implColTestSize(env, inst, CC_E);
85 void cgColIsNEmpty(IRLS& env, const IRInstruction* inst) {
86 implColTestSize(env, inst, CC_NE);
89 void cgCountCollection(IRLS& env, const IRInstruction* inst) {
90 auto const src = srcLoc(env, inst, 0).reg();
91 auto const dst = dstLoc(env, inst, 0).reg();
92 auto& v = vmain(env);
93 v << loadzlq{src[collections::FAST_SIZE_OFFSET], dst};
96 void cgNewCol(IRLS& env, const IRInstruction* inst) {
97 auto const target = [&] {
98 auto const col_type = inst->extra<NewCol>()->type;
99 auto const helper = collections::allocEmptyFunc(col_type);
100 return CallSpec::direct(helper);
101 }();
102 cgCallHelper(vmain(env), env, target, callDest(env, inst),
103 SyncOptions::Sync, argGroup(env, inst));
106 IMPL_OPCODE_CALL(NewPair)
108 void cgNewColFromArray(IRLS& env, const IRInstruction* inst) {
109 auto const target = [&] {
110 auto const col_type = inst->extra<NewColFromArray>()->type;
111 auto const helper = collections::allocFromArrayFunc(col_type);
112 return CallSpec::direct(helper);
113 }();
114 cgCallHelper(vmain(env), env, target, callDest(env, inst),
115 SyncOptions::Sync, argGroup(env, inst).ssa(0));
118 void cgLdColVec(IRLS& env, const IRInstruction* inst) {
119 auto const ty = inst->src(0)->type();
120 auto const cls = ty.clsSpec().cls();
122 auto const src = srcLoc(env, inst, 0).reg();
123 auto const dst = dstLoc(env, inst, 0).reg();
124 auto& v = vmain(env);
126 always_assert_flog(
127 ty == TBottom ||
128 collections::isType(cls, CollectionType::Vector, CollectionType::ImmVector),
129 "LdColVec received an unsupported type: {}\n",
130 ty.toString()
133 v << load{src[BaseVector::arrOffset()], dst};
136 void cgLdColDict(IRLS& env, const IRInstruction* inst) {
137 auto const ty = inst->src(0)->type();
138 auto const cls = ty.clsSpec().cls();
140 auto const src = srcLoc(env, inst, 0).reg();
141 auto const dst = dstLoc(env, inst, 0).reg();
142 auto& v = vmain(env);
144 always_assert_flog(
145 ty == TBottom ||
146 collections::isType(cls,
147 CollectionType::Map, CollectionType::ImmMap,
148 CollectionType::Set, CollectionType::ImmSet),
149 "LdColDict received an unsupported type: {}\n",
150 ty.toString()
153 v << load{src[HashCollection::arrOffset()], dst};
156 ///////////////////////////////////////////////////////////////////////////////
157 // Vector
159 namespace {
161 void assertHasVectorSrc(const IRInstruction* inst, bool imm_allowed) {
162 DEBUG_ONLY auto const vec = inst->src(0);
163 assertx(vec->type() < TObj);
165 if (imm_allowed) {
166 assertx(collections::isType(vec->type().clsSpec().cls(),
167 CollectionType::Vector,
168 CollectionType::ImmVector));
169 } else {
170 assertx(collections::isType(vec->type().clsSpec().cls(),
171 CollectionType::Vector));
177 void cgLdVectorSize(IRLS& env, const IRInstruction* inst) {
178 assertHasVectorSrc(inst, true);
180 auto const src = srcLoc(env, inst, 0).reg();
181 auto const dst = dstLoc(env, inst, 0).reg();
182 auto& v = vmain(env);
183 v << loadzlq{src[BaseVector::sizeOffset()], dst};
186 void cgLdVectorBase(IRLS& env, const IRInstruction* inst) {
187 assertHasVectorSrc(inst, true);
189 auto const src = srcLoc(env, inst, 0).reg();
190 auto const dst = dstLoc(env, inst, 0).reg();
191 auto& v = vmain(env);
193 auto const arr = v.makeReg();
194 v << load{src[BaseVector::arrOffset()], arr};
195 v << lea{arr[PackedArray::entriesOffset()], dst};
198 ///////////////////////////////////////////////////////////////////////////////
199 // Pair
201 void cgLdPairBase(IRLS& env, const IRInstruction* inst) {
202 DEBUG_ONLY auto const pair = inst->src(0);
203 assertx(pair->type() < TObj);
204 assertx(collections::isType(pair->type().clsSpec().cls(),
205 CollectionType::Pair));
207 auto const src = srcLoc(env, inst, 0).reg();
208 auto const dst = dstLoc(env, inst, 0).reg();
209 vmain(env) << lea{src[c_Pair::dataOffset()], dst};
212 ///////////////////////////////////////////////////////////////////////////////