From ece0fc821b89c0500645d5a6e9c6ff41b6f4be9a Mon Sep 17 00:00:00 2001 From: lifansheng Date: Wed, 8 Sep 2021 14:48:34 +0800 Subject: [PATCH 1/2] Add globalrecord Signed-off-by: lifansheng --- ecmascript/ecma_vm.cpp | 2 ++ ecmascript/global_env.h | 3 +- ecmascript/interpreter/interpreter-inl.h | 7 +++-- ecmascript/interpreter/slow_runtime_stub.cpp | 30 ++++++++++++++++++-- ecmascript/interpreter/slow_runtime_stub.h | 1 + 5 files changed, 38 insertions(+), 5 deletions(-) diff --git a/ecmascript/ecma_vm.cpp b/ecmascript/ecma_vm.cpp index 4962c89386..fa1210b0d7 100644 --- a/ecmascript/ecma_vm.cpp +++ b/ecmascript/ecma_vm.cpp @@ -33,6 +33,7 @@ #include "ecmascript/js_invoker.h" #include "ecmascript/js_thread.h" #include "ecmascript/mem/heap.h" +#include "ecmascript/tagged_dictionary.h" #include "ecmascript/object_factory.h" #include "ecmascript/regexp/regexp_parser_cache.h" #include "ecmascript/runtime_call_id.h" @@ -151,6 +152,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_))); JSTaggedValue emptyStr = thread_->GlobalConstants()->GetEmptyString(); stringTable_->InternEmptyString(EcmaString::Cast(emptyStr.GetTaggedObject())); globalEnv->SetEmptyTaggedQueue(thread_, factory_->NewTaggedQueue(0)); diff --git a/ecmascript/global_env.h b/ecmascript/global_env.h index 6ea196415b..3d5dc234aa 100644 --- a/ecmascript/global_env.h +++ b/ecmascript/global_env.h @@ -137,7 +137,8 @@ class JSThread; V(JSTaggedValue, JSIntlBoundFunctionClass, JS_INTL_BOUND_FUNCTION_CLASS) \ V(JSTaggedValue, NumberFormatLocales, NUMBER_FORMAT_LOCALES_INDEX) \ V(JSTaggedValue, DateTimeFormatLocales, DATE_TIMEFORMAT_LOCALES_INDEX) \ - V(JSTaggedValue, JSNativeObjectClass, JS_NATIVE_OBJECT_CLASS) + V(JSTaggedValue, JSNativeObjectClass, JS_NATIVE_OBJECT_CLASS) \ + V(JSTaggedValue, GlobalRecord, GLOBAL_RECORD) class GlobalEnv : public TaggedObject { public: diff --git a/ecmascript/interpreter/interpreter-inl.h b/ecmascript/interpreter/interpreter-inl.h index aec2acf5d2..2932e582ec 100644 --- a/ecmascript/interpreter/interpreter-inl.h +++ b/ecmascript/interpreter/interpreter-inl.h @@ -2623,9 +2623,12 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool bool found = false; FastRuntimeStub::GetGlobalOwnProperty(globalObj, propKey, &found); if (!found) { - // slow path will throw exception - JSTaggedValue res = SlowRuntimeStub::TryStGlobalByName(thread, propKey); + // find globalreord + JSTaggedValue value = GET_ACC(); + SAVE_ACC(); + JSTaggedValue res = SlowRuntimeStub::StGlobalRecord(thread, propKey, value); INTERPRETER_RETURN_IF_ABRUPT(res); + RESTORE_ACC(); } else { JSTaggedValue value = GET_ACC(); SAVE_ACC(); diff --git a/ecmascript/interpreter/slow_runtime_stub.cpp b/ecmascript/interpreter/slow_runtime_stub.cpp index 8e5c86d631..64d66802bf 100644 --- a/ecmascript/interpreter/slow_runtime_stub.cpp +++ b/ecmascript/interpreter/slow_runtime_stub.cpp @@ -36,6 +36,7 @@ #include "ecmascript/js_proxy.h" #include "ecmascript/js_tagged_value-inl.h" #include "ecmascript/js_thread.h" +#include "ecmascript/tagged_dictionary.h" #include "ecmascript/runtime_call_id.h" #include "ecmascript/template_string.h" #include "ecmascript/vmstat/runtime_stat.h" @@ -1243,10 +1244,18 @@ JSTaggedValue SlowRuntimeStub::TryLdGlobalByName(JSThread *thread, JSTaggedValue JSHandle obj(thread, global.GetTaggedObject()->GetClass()->GetPrototype()); JSHandle propHandle(thread, prop); OperationResult res = JSTaggedValue::GetProperty(thread, obj, propHandle); - if (!res.GetPropertyMetaData().IsFound()) { + if (res.GetPropertyMetaData().IsFound()) { + return res.GetValue().GetTaggedValue(); + } + + EcmaVM *vm = thread->GetEcmaVM(); + JSHandle env = vm->GetGlobalEnv(); + NameDictionary *dict = NameDictionary::Cast(env->GetGlobalRecord()->GetTaggedObject()); + int entry = dict->FindEntry(propHandle.GetTaggedValue()); + if (entry == -1) { return ThrowReferenceError(thread, prop, " is not defined"); } - return res.GetValue().GetTaggedValue(); + return dict->GetValue(entry); } JSTaggedValue SlowRuntimeStub::TryStGlobalByName(JSThread *thread, JSTaggedValue prop) @@ -1279,6 +1288,23 @@ JSTaggedValue SlowRuntimeStub::StGlobalVar(JSThread *thread, JSTaggedValue prop, return JSTaggedValue::True(); } +JSTaggedValue SlowRuntimeStub::StGlobalRecord(JSThread *thread, JSTaggedValue prop, JSTaggedValue value) +{ + [[maybe_unused]] EcmaHandleScope handleScope(thread); + + EcmaVM *vm = thread->GetEcmaVM(); + JSHandle env = vm->GetGlobalEnv(); + NameDictionary *dict = NameDictionary::Cast(env->GetGlobalRecord()->GetTaggedObject()); + + int entry = dict->FindEntry(prop); + if (entry == -1) { + return ThrowReferenceError(thread, prop, " is not defined"); + } + dict->UpdateValue(thread, entry, value); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + return JSTaggedValue::True(); +} + JSTaggedValue SlowRuntimeStub::ThrowReferenceError(JSThread *thread, JSTaggedValue prop, const char *desc) { [[maybe_unused]] EcmaHandleScope handleScope(thread); diff --git a/ecmascript/interpreter/slow_runtime_stub.h b/ecmascript/interpreter/slow_runtime_stub.h index b67e7d3fc3..264a591b69 100644 --- a/ecmascript/interpreter/slow_runtime_stub.h +++ b/ecmascript/interpreter/slow_runtime_stub.h @@ -120,6 +120,7 @@ public: static JSTaggedValue TryStGlobalByName(JSThread *thread, JSTaggedValue prop); static JSTaggedValue LdGlobalVar(JSThread *thread, JSTaggedValue global, JSTaggedValue prop); static JSTaggedValue StGlobalVar(JSThread *thread, JSTaggedValue prop, JSTaggedValue value); + static JSTaggedValue StGlobalRecord(JSThread *thread, JSTaggedValue prop, JSTaggedValue value); static JSTaggedValue StArraySpread(JSThread *thread, JSTaggedValue dst, JSTaggedValue index, JSTaggedValue src); static JSTaggedValue DefineGeneratorFunc(JSThread *thread, JSFunction *func); -- Gitee From fad58f0ade2db0d80f7b441698261d5e975f468b Mon Sep 17 00:00:00 2001 From: lifansheng Date: Wed, 8 Sep 2021 17:28:07 +0800 Subject: [PATCH 2/2] add globalrecord Signed-off-by: lifansheng --- ecmascript/interpreter/interpreter-inl.h | 41 +++++++++++++++++++- ecmascript/interpreter/interpreter.h | 3 ++ ecmascript/interpreter/slow_runtime_stub.cpp | 26 ++++++++++++- ecmascript/interpreter/slow_runtime_stub.h | 3 +- ecmascript/property_attributes.h | 13 ++++++- 5 files changed, 81 insertions(+), 5 deletions(-) diff --git a/ecmascript/interpreter/interpreter-inl.h b/ecmascript/interpreter/interpreter-inl.h index 2932e582ec..ab5e01d7c0 100644 --- a/ecmascript/interpreter/interpreter-inl.h +++ b/ecmascript/interpreter/interpreter-inl.h @@ -2626,7 +2626,7 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool // find globalreord JSTaggedValue value = GET_ACC(); SAVE_ACC(); - JSTaggedValue res = SlowRuntimeStub::StGlobalRecord(thread, propKey, value); + JSTaggedValue res = SlowRuntimeStub::UpdateGlobalRecord(thread, propKey, value); INTERPRETER_RETURN_IF_ABRUPT(res); RESTORE_ACC(); } else { @@ -2638,6 +2638,45 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool } DISPATCH(BytecodeInstruction::Format::IMM8_ID32_IMM16); } + HANDLE_OPCODE(HANDLE_BUILTIN_STCONSTTOGLOBALRECORD_PREF_ID32) { + uint32_t stringId = READ_INST_32_1(); + JSTaggedValue propKey = constpool->GetObjectFromCache(stringId); + LOG_INST() << "intrinsics::stconsttoglobalrecord" + << " stringId:" << stringId << ", " << ConvertToString(EcmaString::Cast(propKey.GetTaggedObject())); + + JSTaggedValue value = GET_ACC(); + SAVE_ACC(); + JSTaggedValue res = SlowRuntimeStub::StGlobalRecord(thread, propKey, value, true); + INTERPRETER_RETURN_IF_ABRUPT(res); + DISPATCH(BytecodeInstruction::Format::PREF_ID32); + } + + HANDLE_OPCODE(HANDLE_BUILTIN_STLETTOGLOBALRECORD_PREF_ID32) { + uint32_t stringId = READ_INST_32_1(); + JSTaggedValue propKey = constpool->GetObjectFromCache(stringId); + LOG_INST() << "intrinsics::stlettoglobalrecord" + << " stringId:" << stringId << ", " << ConvertToString(EcmaString::Cast(propKey.GetTaggedObject())); + + JSTaggedValue value = GET_ACC(); + SAVE_ACC(); + JSTaggedValue res = SlowRuntimeStub::StGlobalRecord(thread, propKey, value, false); + INTERPRETER_RETURN_IF_ABRUPT(res); + DISPATCH(BytecodeInstruction::Format::PREF_ID32); + } + + HANDLE_OPCODE(HANDLE_BUILTIN_STCLASSTOGLOBALRECORD_PREF_ID32) { + uint32_t stringId = READ_INST_32_1(); + JSTaggedValue propKey = constpool->GetObjectFromCache(stringId); + LOG_INST() << "intrinsics::stclasstoglobalrecord" + << " stringId:" << stringId << ", " << ConvertToString(EcmaString::Cast(propKey.GetTaggedObject())); + + JSTaggedValue value = GET_ACC(); + SAVE_ACC(); + JSTaggedValue res = SlowRuntimeStub::StGlobalRecord(thread, propKey, value, false); + INTERPRETER_RETURN_IF_ABRUPT(res); + DISPATCH(BytecodeInstruction::Format::PREF_ID32); + } + HANDLE_OPCODE(HANDLE_BUILTIN_LDGLOBALVAR_IMM8_ID32_IMM16) { uint32_t stringId = READ_INST_32_1(); JSTaggedValue propKey = constpool->GetObjectFromCache(stringId); diff --git a/ecmascript/interpreter/interpreter.h b/ecmascript/interpreter/interpreter.h index d3ba2aa5d1..f6be3d6c2d 100644 --- a/ecmascript/interpreter/interpreter.h +++ b/ecmascript/interpreter/interpreter.h @@ -213,6 +213,9 @@ enum EcmaOpcode { DEFINEMETHOD_IMM8_ID16_V8, TRYLDGLOBALBYNAME_IMM8_ID32_IMM16, TRYSTGLOBALBYNAME_IMM8_ID32_IMM16, + STCONSTTOGLOBALRECORD_PREF_ID32; + STLETTOGLOBALRECORD_PREF_ID32; + STCLASSTOGLOBALRECORD_PREF_ID32; LDGLOBALVAR_IMM8_ID32_IMM16, STGLOBALVAR_IMM8_ID32_IMM16, LDOBJBYNAME_IMM8_ID32_IMM16_V8, diff --git a/ecmascript/interpreter/slow_runtime_stub.cpp b/ecmascript/interpreter/slow_runtime_stub.cpp index 64d66802bf..c789455a18 100644 --- a/ecmascript/interpreter/slow_runtime_stub.cpp +++ b/ecmascript/interpreter/slow_runtime_stub.cpp @@ -1288,7 +1288,7 @@ JSTaggedValue SlowRuntimeStub::StGlobalVar(JSThread *thread, JSTaggedValue prop, return JSTaggedValue::True(); } -JSTaggedValue SlowRuntimeStub::StGlobalRecord(JSThread *thread, JSTaggedValue prop, JSTaggedValue value) +JSTaggedValue SlowRuntimeStub::UpdateGlobalRecord(JSThread *thread, JSTaggedValue prop, JSTaggedValue value) { [[maybe_unused]] EcmaHandleScope handleScope(thread); @@ -1300,7 +1300,29 @@ JSTaggedValue SlowRuntimeStub::StGlobalRecord(JSThread *thread, JSTaggedValue pr if (entry == -1) { return ThrowReferenceError(thread, prop, " is not defined"); } - dict->UpdateValue(thread, entry, value); + if (!dict->GetAttributes(entry).IsConstField()) { + dict->UpdateValue(thread, entry, value); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + } + return JSTaggedValue::True(); +} + +JSTaggedValue SlowRuntimeStub::StGlobalRecord(JSThread *thread, JSTaggedValue prop, JSTaggedValue value, bool isConst) +{ + [[maybe_unused]] EcmaHandleScope handleScope(thread); + + EcmaVM *vm = thread->GetEcmaVM(); + JSHandle env = vm->GetGlobalEnv(); + NameDictionary *dict = NameDictionary::Cast(env->GetGlobalRecord()->GetTaggedObject()); + + int entry = dict->FindEntry(prop); + if (entry == -1) { + return ThrowReferenceError(thread, prop, " is not defined"); + } + + PropertyAttributes attributes; + attributes.SetIsConstField(isConst); + dict->SetEntry(thread, entry, prop, value, attributes); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); return JSTaggedValue::True(); } diff --git a/ecmascript/interpreter/slow_runtime_stub.h b/ecmascript/interpreter/slow_runtime_stub.h index 264a591b69..ecacb260a1 100644 --- a/ecmascript/interpreter/slow_runtime_stub.h +++ b/ecmascript/interpreter/slow_runtime_stub.h @@ -120,7 +120,8 @@ public: static JSTaggedValue TryStGlobalByName(JSThread *thread, JSTaggedValue prop); static JSTaggedValue LdGlobalVar(JSThread *thread, JSTaggedValue global, JSTaggedValue prop); static JSTaggedValue StGlobalVar(JSThread *thread, JSTaggedValue prop, JSTaggedValue value); - static JSTaggedValue StGlobalRecord(JSThread *thread, JSTaggedValue prop, JSTaggedValue value); + static JSTaggedValue StGlobalRecord(JSThread *thread, JSTaggedValue prop, JSTaggedValue value, bool isConst); + static JSTaggedValue UpdateGlobalRecord(JSThread *thread, JSTaggedValue prop, JSTaggedValue value); static JSTaggedValue StArraySpread(JSThread *thread, JSTaggedValue dst, JSTaggedValue index, JSTaggedValue src); static JSTaggedValue DefineGeneratorFunc(JSThread *thread, JSFunction *func); diff --git a/ecmascript/property_attributes.h b/ecmascript/property_attributes.h index 0dae6320a7..5aada1faa3 100644 --- a/ecmascript/property_attributes.h +++ b/ecmascript/property_attributes.h @@ -76,7 +76,7 @@ public: static constexpr uint32_t NORMAL_ATTR_BITS = 18; using NormalAttrField = BitField; using SortedIndexField = OffsetField::NextField; // 28 - + using IsConstField = SortedIndexField::NextFlag; // 29 // dictionary mode, include global using PropertyBoxTypeField = PropertyMetaDataField::NextField; // 2: 2 bits, 5-6 using DictionaryOrderField = PropertyBoxTypeField::NextField; // 26 @@ -217,10 +217,21 @@ public: return IsInlinedPropsField::Get(value_); } + inline void SetIsConstField(bool flag) + { + IsConstField::Set(flag, &value_); + } + + inline bool IsConstField() const + { + return IsConstField::Get(value_); + } + inline void SetRepresentation(Representation representation) { RepresentationField::Set(representation, &value_); } + inline Representation GetRepresentation() const { return RepresentationField::Get(value_); -- Gitee