add global record to IC

Signed-off-by: ding <dingding5@huawei.com>
This commit is contained in:
ding 2021-10-12 16:57:22 +08:00
parent c94dc68208
commit 8f551973b8
6 changed files with 48 additions and 19 deletions

View File

@ -22,6 +22,7 @@
#include "ecmascript/class_linker/program_object-inl.h"
#include "ecmascript/ecma_module.h"
#include "ecmascript/ecma_string_table.h"
#include "ecmascript/global_dictionary.h"
#include "ecmascript/global_env.h"
#include "ecmascript/global_env_constants-inl.h"
#include "ecmascript/global_env_constants.h"
@ -153,7 +154,7 @@ bool EcmaVM::Initialize()
globalEnv->SetEmptyArray(thread_, factory_->NewEmptyArray());
globalEnv->SetEmptyLayoutInfo(thread_, factory_->CreateLayoutInfo(0));
globalEnv->SetRegisterSymbols(thread_, JSTaggedValue(SymbolTable::Create(thread_)));
globalEnv->SetGlobalRecord(thread_, JSTaggedValue(NameDictionary::Create(thread_)));
globalEnv->SetGlobalRecord(thread_, JSTaggedValue(GlobalDictionary::Create(thread_)));
JSTaggedValue emptyStr = thread_->GlobalConstants()->GetEmptyString();
stringTable_->InternEmptyString(EcmaString::Cast(emptyStr.GetTaggedObject()));
globalEnv->SetEmptyTaggedQueue(thread_, factory_->NewTaggedQueue(0));

View File

@ -136,15 +136,18 @@ JSTaggedValue LoadICRuntime::LoadMiss(JSHandle<JSTaggedValue> receiver, JSHandle
if (receiver->IsTypedArray() || !receiver->IsJSObject()) {
return JSTaggedValue::GetProperty(thread_, receiver, key).GetValue().GetTaggedValue();
}
// 1. find from global record
// global variable find from global record firstly
if (GetICKind() == ICKind::NamedGlobalLoadIC) {
bool found = false;
JSTaggedValue res = SlowRuntimeStub::LdGlobalRecord(thread_, key.GetTaggedValue(), &found);
JSTaggedValue box = SlowRuntimeStub::LdGlobalRecord(thread_, key.GetTaggedValue(), &found);
if (found) {
return res;
ASSERT(box.IsPropertyBox());
icAccessor_.AddGlobalRecordHandler(JSHandle<JSTaggedValue>(thread_, box));
return PropertyBox::Cast(box.GetTaggedObject())->GetValue();
}
}
// 2. find from global object
ObjectOperator op(GetThread(), receiver, key);
auto result = JSHandle<JSTaggedValue>(thread_, JSObject::GetProperty(GetThread(), &op));
if (!op.IsFound() && GetICKind() == ICKind::NamedGlobalLoadIC) {
@ -176,18 +179,21 @@ JSTaggedValue StoreICRuntime::StoreMiss(JSHandle<JSTaggedValue> receiver, JSHand
bool success = JSTaggedValue::SetProperty(GetThread(), receiver, key, value, true);
return success ? JSTaggedValue::Undefined() : JSTaggedValue::Exception();
}
// 1. find from global record
// global variable find from global record firstly
if (GetICKind() == ICKind::NamedGlobalStoreIC) {
bool found = false;
SlowRuntimeStub::LdGlobalRecord(thread_, key.GetTaggedValue(), &found);
JSTaggedValue box = SlowRuntimeStub::LdGlobalRecord(thread_, key.GetTaggedValue(), &found);
if (found) {
ASSERT(box.IsPropertyBox());
SlowRuntimeStub::TryUpdateGlobalRecord(thread_, key.GetTaggedValue(), value.GetTaggedValue());
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread_);
icAccessor_.AddGlobalRecordHandler(JSHandle<JSTaggedValue>(thread_, box));
return JSTaggedValue::Undefined();
}
}
UpdateReceiverHClass(JSHandle<JSTaggedValue>(GetThread(), JSHandle<JSObject>::Cast(receiver)->GetClass()));
// 2. find from global object
ObjectOperator op(GetThread(), receiver, key);
bool success = JSObject::SetProperty(&op, value, true);
if (!success && GetICKind() == ICKind::NamedGlobalStoreIC) {

View File

@ -181,6 +181,12 @@ void ProfileTypeAccessor::AddGlobalHandlerKey(JSHandle<JSTaggedValue> key, JSHan
profileTypeInfo_->Set(thread_, index, newArr.GetTaggedValue());
}
void ProfileTypeAccessor::AddGlobalRecordHandler(JSHandle<JSTaggedValue> handler) const
{
uint32_t index = slotId_;
profileTypeInfo_->Set(thread_, index, handler.GetTaggedValue());
}
void ProfileTypeAccessor::SetAsMega() const
{
profileTypeInfo_->Set(thread_, slotId_, JSTaggedValue::Hole());

View File

@ -116,6 +116,7 @@ public:
void AddHandlerWithKey(JSHandle<JSTaggedValue> key, JSHandle<JSTaggedValue> dynclass,
JSHandle<JSTaggedValue> handler) const;
void AddGlobalHandlerKey(JSHandle<JSTaggedValue> key, JSHandle<JSTaggedValue> handler) const;
void AddGlobalRecordHandler(JSHandle<JSTaggedValue> handler) const;
JSTaggedValue GetWeakRef(JSTaggedValue value) const
{

View File

@ -2640,7 +2640,7 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool
// order: 1. global record 2. global object
JSTaggedValue result = SlowRuntimeStub::LdGlobalRecord(thread, prop, &found);
if (found) {
SET_ACC(result);
SET_ACC(PropertyBox::Cast(result.GetTaggedObject())->GetValue());
} else {
JSTaggedValue globalResult = FastRuntimeStub::GetGlobalOwnProperty(globalObj, prop, &found);
if (found) {

View File

@ -1380,16 +1380,21 @@ JSTaggedValue SlowRuntimeStub::TryUpdateGlobalRecord(JSThread *thread, JSTaggedV
EcmaVM *vm = thread->GetEcmaVM();
JSHandle<GlobalEnv> env = vm->GetGlobalEnv();
NameDictionary *dict = NameDictionary::Cast(env->GetGlobalRecord()->GetTaggedObject());
GlobalDictionary *dict = GlobalDictionary::Cast(env->GetGlobalRecord()->GetTaggedObject());
int entry = dict->FindEntry(prop);
ASSERT(entry != -1);
if (dict->GetAttributes(entry).IsConstProps()) {
return ThrowSyntaxError(thread, " const can not be modified");
return ThrowSyntaxError(thread, "const variable can not be modified");
}
dict->UpdateValue(thread, entry, value);
PropertyBox *box = dict->GetBox(entry);
box->SetValue(thread, value);
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
return JSTaggedValue::True();
}
// return box
JSTaggedValue SlowRuntimeStub::LdGlobalRecord(JSThread *thread, JSTaggedValue key, bool *found)
{
INTERPRETER_TRACE(thread, LdGlobalRecord);
@ -1397,11 +1402,11 @@ JSTaggedValue SlowRuntimeStub::LdGlobalRecord(JSThread *thread, JSTaggedValue ke
EcmaVM *vm = thread->GetEcmaVM();
JSHandle<GlobalEnv> env = vm->GetGlobalEnv();
NameDictionary *dict = NameDictionary::Cast(env->GetGlobalRecord()->GetTaggedObject());
GlobalDictionary *dict = GlobalDictionary::Cast(env->GetGlobalRecord()->GetTaggedObject());
int entry = dict->FindEntry(key);
if (entry != -1) {
*found = true;
return dict->GetValue(entry);
return JSTaggedValue(dict->GetBox(entry));
}
return JSTaggedValue::Undefined();
}
@ -1413,18 +1418,28 @@ JSTaggedValue SlowRuntimeStub::StGlobalRecord(JSThread *thread, JSTaggedValue pr
EcmaVM *vm = thread->GetEcmaVM();
JSHandle<GlobalEnv> env = vm->GetGlobalEnv();
NameDictionary *dict = NameDictionary::Cast(env->GetGlobalRecord()->GetTaggedObject());
GlobalDictionary *dict = GlobalDictionary::Cast(env->GetGlobalRecord()->GetTaggedObject());
// cross files global record name binding judgment
int entry = dict->FindEntry(prop);
if (entry != -1) {
return ThrowReferenceError(thread, prop, " is not defined");
return ThrowSyntaxError(thread, "Duplicate identifier");
}
PropertyAttributes attributes;
attributes.SetIsConstProps(isConst);
if (isConst) {
attributes.SetIsConstProps(true);
}
JSHandle<JSTaggedValue> propHandle(thread, prop);
JSHandle<JSTaggedValue> valueHandle(thread, value);
JSHandle<NameDictionary> dictHandle(thread, dict);
dict->PutIfAbsent(thread, dictHandle, propHandle, valueHandle, attributes);
JSHandle<GlobalDictionary> dictHandle(thread, dict);
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSHandle<PropertyBox> box = factory->NewPropertyBox(valueHandle);
PropertyBoxType boxType = valueHandle->IsUndefined() ? PropertyBoxType::UNDEFINED : PropertyBoxType::CONSTANT;
attributes.SetBoxType(boxType);
dict->PutIfAbsent(thread, dictHandle, propHandle, JSHandle<JSTaggedValue>(box), attributes);
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
return JSTaggedValue::True();
}