Skip to content

Commit 6ebbd22

Browse files
committed
Optimize very big object expression through big bloom filter
Signed-off-by: Seonghyun Kim <sh8281.kim@samsung.com>
1 parent 069fba1 commit 6ebbd22

File tree

3 files changed

+56
-30
lines changed

3 files changed

+56
-30
lines changed

src/interpreter/ByteCode.h

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -966,24 +966,30 @@ class CreateObjectPrepare : public ByteCode {
966966
};
967967

968968
typedef BloomFilter<1024> CreateObjectPropertyFilter;
969+
typedef BloomFilter<1024 * 64> CreateObjectBigPropertyFilter;
969970

970971
struct CreateObjectData : public gc {
971-
bool m_allPrecomputed;
972-
bool m_wasStructureComputed;
973-
bool m_canStoreStructureOnCode;
974-
bool m_needsToUsePropertyFilterOnIntepreter;
972+
bool m_allPrecomputed : 1;
973+
bool m_wasStructureComputed : 1;
974+
bool m_canStoreStructureOnCode : 1;
975+
bool m_needsToUsePropertyFilterOnInterpreter : 1;
976+
bool m_needsToUseBigPropertyFilterOnInterpreter : 1;
975977
VectorWithInlineStorage<6, ObjectStructureItem, GCUtil::gc_malloc_allocator<ObjectStructureItem>> m_properties;
976978
EncodedValueVector m_values;
977979
Object* m_target;
978980
CreateObjectPrepare* m_initCode;
979-
Optional<CreateObjectPropertyFilter*> m_filter;
981+
union {
982+
Optional<CreateObjectPropertyFilter*> m_filter;
983+
Optional<CreateObjectBigPropertyFilter*> m_bigFilter;
984+
};
980985
CreateObjectData(bool allPrecomputed, bool wasStructureComputed, bool canStoreStructureOnCode,
981-
bool needsToUsePropertyFilterOnIntepreter,
986+
bool needsToUsePropertyFilterOnInterpreter, bool needsToUseBigPropertyFilterOnInterpreter,
982987
size_t reserveSize, Object* target, CreateObjectPrepare* initCode)
983988
: m_allPrecomputed(allPrecomputed)
984989
, m_wasStructureComputed(wasStructureComputed)
985990
, m_canStoreStructureOnCode(canStoreStructureOnCode)
986-
, m_needsToUsePropertyFilterOnIntepreter(needsToUsePropertyFilterOnIntepreter)
991+
, m_needsToUsePropertyFilterOnInterpreter(needsToUsePropertyFilterOnInterpreter)
992+
, m_needsToUseBigPropertyFilterOnInterpreter(needsToUseBigPropertyFilterOnInterpreter)
987993
, m_target(target)
988994
, m_initCode(initCode)
989995
{
@@ -994,11 +1000,13 @@ class CreateObjectPrepare : public ByteCode {
9941000
}
9951001
};
9961002

997-
CreateObjectPrepare(const ByteCodeLOC& loc, const size_t dataRegisterIndex, const size_t objectIndex, bool needsToUseNameFilterOnIntepreter)
1003+
CreateObjectPrepare(const ByteCodeLOC& loc, const size_t dataRegisterIndex, const size_t objectIndex, bool needsToUseNameFilterOnIntepreter,
1004+
bool needsToUseBigPropertyFilterOnInterpreter)
9981005
: ByteCode(Opcode::CreateObjectPrepareOpcode, loc)
9991006
, m_stage(Stage::Init)
10001007
, m_allPrecomputed(false)
1001-
, m_needsToUsePropertyFilterOnIntepreter(needsToUseNameFilterOnIntepreter)
1008+
, m_needsToUsePropertyFilterOnInterpreter(needsToUseNameFilterOnIntepreter)
1009+
, m_needsToUseBigPropertyFilterOnInterpreter(needsToUseBigPropertyFilterOnInterpreter)
10021010
, m_hasPrecomputedKey(false)
10031011
, m_needsToUpdateFunctionName(false)
10041012
, m_isGetter(false)
@@ -1012,7 +1020,8 @@ class CreateObjectPrepare : public ByteCode {
10121020
: ByteCode(Opcode::CreateObjectPrepareOpcode, loc)
10131021
, m_stage(Stage::FillKeyValue)
10141022
, m_allPrecomputed(false)
1015-
, m_needsToUsePropertyFilterOnIntepreter(false)
1023+
, m_needsToUsePropertyFilterOnInterpreter(false)
1024+
, m_needsToUseBigPropertyFilterOnInterpreter(false)
10161025
, m_hasPrecomputedKey(hasPreComputedKey)
10171026
, m_needsToUpdateFunctionName(needsToUpdateFunctionName)
10181027
, m_isGetter(false)
@@ -1026,7 +1035,8 @@ class CreateObjectPrepare : public ByteCode {
10261035
: ByteCode(Opcode::CreateObjectPrepareOpcode, loc)
10271036
, m_stage(Stage::DefineGetterSetter)
10281037
, m_allPrecomputed(false)
1029-
, m_needsToUsePropertyFilterOnIntepreter(false)
1038+
, m_needsToUsePropertyFilterOnInterpreter(false)
1039+
, m_needsToUseBigPropertyFilterOnInterpreter(false)
10301040
, m_hasPrecomputedKey(hasPreComputedKey)
10311041
, m_needsToUpdateFunctionName(false)
10321042
, m_isGetter(isGetter)
@@ -1038,7 +1048,8 @@ class CreateObjectPrepare : public ByteCode {
10381048

10391049
Stage m_stage : 2;
10401050
bool m_allPrecomputed : 1;
1041-
bool m_needsToUsePropertyFilterOnIntepreter : 1;
1051+
bool m_needsToUsePropertyFilterOnInterpreter : 1;
1052+
bool m_needsToUseBigPropertyFilterOnInterpreter : 1;
10421053
bool m_hasPrecomputedKey : 1;
10431054
bool m_needsToUpdateFunctionName : 1;
10441055
bool m_isGetter : 1; // other case, this is setter

src/interpreter/ByteCodeInterpreter.cpp

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3059,6 +3059,13 @@ NEVER_INLINE void InterpreterSlowPath::createObjectOperation(ExecutionState& sta
30593059
}
30603060
}
30613061
obj->m_values.reset(data->m_values.takeBuffer());
3062+
3063+
if (UNLIKELY(data->m_needsToUseBigPropertyFilterOnInterpreter)) {
3064+
if (data->m_bigFilter) {
3065+
GC_FREE(data->m_bigFilter.value());
3066+
}
3067+
}
3068+
30623069
if (isAsyncOrGenerator) {
30633070
GC_FREE(data);
30643071
} else {
@@ -3105,23 +3112,24 @@ NEVER_INLINE void InterpreterSlowPath::createObjectPrepareOperation(ExecutionSta
31053112
}
31063113
CreateObjectPrepare::CreateObjectData* data = new (ptr) CreateObjectPrepare::CreateObjectData(
31073114
code->m_allPrecomputed, code->m_cachedObjectStructure.hasValue(), code->m_allPrecomputed,
3108-
code->m_needsToUsePropertyFilterOnIntepreter,
3115+
code->m_needsToUsePropertyFilterOnInterpreter, code->m_needsToUseBigPropertyFilterOnInterpreter,
31093116
code->m_propertyReserveSize, new Object(state), code);
31103117
registerFile[code->m_objectIndex] = data->m_target;
31113118
if (data->m_wasStructureComputed) {
31123119
data->m_target->m_structure = code->m_cachedObjectStructure.value();
31133120
}
3114-
if (UNLIKELY(data->m_needsToUsePropertyFilterOnIntepreter)) {
3121+
if (UNLIKELY(data->m_needsToUsePropertyFilterOnInterpreter)) {
31153122
if (byteCodeBlock->codeBlock()->isAsyncOrGenerator()) {
31163123
data->m_filter = new (PointerFreeGC) CreateObjectPrepare::CreateObjectPropertyFilter();
31173124
} else {
31183125
size_t diff = sizeof(CreateObjectPrepare::CreateObjectData);
31193126
if (diff % sizeof(Value)) {
31203127
diff += (sizeof(Value) - (diff % sizeof(Value)));
31213128
}
3122-
data->m_filter = reinterpret_cast<CreateObjectPrepare::CreateObjectPropertyFilter*>(ptr + diff);
3129+
data->m_filter = new (reinterpret_cast<void*>(ptr + diff)) CreateObjectPrepare::CreateObjectPropertyFilter;
31233130
}
3124-
data->m_filter->clear();
3131+
} else if (UNLIKELY(data->m_needsToUseBigPropertyFilterOnInterpreter)) {
3132+
data->m_bigFilter = new (PointerFreeGC) CreateObjectPrepare::CreateObjectBigPropertyFilter();
31253133
}
31263134
} else {
31273135
ASSERT(code->m_stage == CreateObjectPrepare::FillKeyValue || code->m_stage == CreateObjectPrepare::DefineGetterSetter);
@@ -3160,20 +3168,24 @@ NEVER_INLINE void InterpreterSlowPath::createObjectPrepareOperation(ExecutionSta
31603168
}
31613169

31623170
bool needsPropertySearch = true;
3163-
if (UNLIKELY(data->m_needsToUsePropertyFilterOnIntepreter)) {
3164-
auto newPropertyNameHash = (propertyName.isSymbol() ?
3165-
propertyName.symbol()->descriptionString()->hashValue() : propertyName.plainString()->hashValue());
3166-
if (data->m_filter->mayContain(newPropertyNameHash)) {
3167-
} else {
3171+
size_t lastPropertyCount = data->m_properties.size();
3172+
size_t targetIndex = lastPropertyCount;
3173+
bool updateProperty = false;
3174+
3175+
if (UNLIKELY(data->m_needsToUsePropertyFilterOnInterpreter)) {
3176+
auto newPropertyNameHash = propertyName.hashValue();
3177+
if (!data->m_filter->mayContain(newPropertyNameHash)) {
31683178
data->m_filter->add(newPropertyNameHash);
31693179
needsPropertySearch = false;
31703180
}
3181+
} else if (UNLIKELY(data->m_needsToUseBigPropertyFilterOnInterpreter)) {
3182+
auto newPropertyNameHash = propertyName.hashValue() * 13;
3183+
if (!data->m_bigFilter->mayContain(newPropertyNameHash)) {
3184+
data->m_bigFilter->add(newPropertyNameHash);
3185+
needsPropertySearch = false;
3186+
}
31713187
}
31723188

3173-
size_t lastPropertyCount = data->m_properties.size();
3174-
size_t targetIndex = lastPropertyCount;
3175-
bool updateProperty = false;
3176-
31773189
if (LIKELY(needsPropertySearch)) {
31783190
for (size_t i = 0; i < lastPropertyCount; i++) {
31793191
if (data->m_properties[i].m_propertyName == propertyName) {

src/parser/ast/ObjectExpressionNode.h

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,12 @@ class ObjectExpressionNode : public ExpressionNode {
6060
size_t objectCreationDataRegisterSize = 0;
6161
size_t initCodePosition = codeBlock->currentCodeSize();
6262

63-
bool needsToUseNameFilterOnIntepreter = m_properties.size() >= 6;
64-
if (needsToUseNameFilterOnIntepreter) {
63+
bool needsToUseBigPropertyFilterOnInterpreter = m_properties.size() >= 512;
64+
bool needsToUseNameFilterOnInterpreter = !needsToUseBigPropertyFilterOnInterpreter && m_properties.size() >= 6;
65+
if (needsToUseNameFilterOnInterpreter || needsToUseBigPropertyFilterOnInterpreter) {
6566
for (SentinelNode* property = m_properties.begin(); property != m_properties.end(); property = property->next()) {
6667
if (!property->astNode()->isProperty()) {
67-
needsToUseNameFilterOnIntepreter = false;
68+
needsToUseBigPropertyFilterOnInterpreter = needsToUseNameFilterOnInterpreter = false;
6869
}
6970
}
7071
}
@@ -79,15 +80,17 @@ class ObjectExpressionNode : public ExpressionNode {
7980
objectCreationDataRegisterSize++;
8081
context->getRegister();
8182
}
82-
if (needsToUseNameFilterOnIntepreter) {
83+
if (needsToUseNameFilterOnInterpreter) {
8384
for (size_t i = 0; i < sizeof(CreateObjectPrepare::CreateObjectPropertyFilter); i += sizeof(Value)) {
8485
objectCreationDataRegisterSize++;
8586
context->getRegister();
8687
}
8788
}
8889
}
8990

90-
codeBlock->pushCode(CreateObjectPrepare(ByteCodeLOC(m_loc.index), objectCreationDataIndex, dstRegister, needsToUseNameFilterOnIntepreter), context, this->m_loc.index);
91+
codeBlock->pushCode(CreateObjectPrepare(ByteCodeLOC(m_loc.index), objectCreationDataIndex, dstRegister,
92+
needsToUseNameFilterOnInterpreter, needsToUseBigPropertyFilterOnInterpreter),
93+
context, this->m_loc.index);
9194
}
9295

9396
bool allPrecomputed = true;

0 commit comments

Comments
 (0)