Commit adfea6af authored by jochen's avatar jochen Committed by Commit bot

[api] Use shallow copy for the template instantiation cache

This means we can't cache templates that have object properties. Disable
caching for those.

BUG=
R=verwaest@chromium.org

Review URL: https://codereview.chromium.org/1753643002

Cr-Commit-Position: refs/heads/master@{#34402}
parent 78d84530
......@@ -300,9 +300,7 @@ MaybeHandle<JSObject> InstantiateObject(Isolate* isolate,
if (entry != UnseededNumberDictionary::kNotFound) {
Object* boilerplate = cache->ValueAt(entry);
result = handle(JSObject::cast(boilerplate), isolate);
ASSIGN_RETURN_ON_EXCEPTION(
isolate, result, JSObject::DeepCopyApiBoilerplate(result), JSObject);
return result;
return isolate->factory()->CopyJSObject(result);
}
}
// Enter a new scope. Recursion could otherwise create a lot of handles.
......@@ -326,8 +324,7 @@ MaybeHandle<JSObject> InstantiateObject(Isolate* isolate,
if (serial_number) {
CacheTemplateInstantiation(isolate, serial_number, result);
ASSIGN_RETURN_ON_EXCEPTION(
isolate, result, JSObject::DeepCopyApiBoilerplate(result), JSObject);
result = isolate->factory()->CopyJSObject(result);
}
return scope.CloseAndEscape(result);
}
......
......@@ -940,9 +940,16 @@ void Template::Set(v8::Local<Name> name, v8::Local<Data> value,
i::Isolate* isolate = templ->GetIsolate();
ENTER_V8(isolate);
i::HandleScope scope(isolate);
auto value_obj = Utils::OpenHandle(*value);
if (value_obj->IsObjectTemplateInfo()) {
templ->set_serial_number(i::Smi::FromInt(0));
if (templ->IsFunctionTemplateInfo()) {
i::Handle<i::FunctionTemplateInfo>::cast(templ)->set_do_not_cache(true);
}
}
// TODO(dcarney): split api to allow values of v8::Value or v8::TemplateInfo.
i::ApiNatives::AddDataProperty(isolate, templ, Utils::OpenHandle(*name),
Utils::OpenHandle(*value),
value_obj,
static_cast<i::PropertyAttributes>(attribute));
}
......
......@@ -7922,9 +7922,7 @@ Handle<Object> JSObject::FastPropertyAt(Handle<JSObject> object,
return Object::WrapForRead(isolate, raw_value, representation);
}
enum class BoilerplateKind { kNormalBoilerplate, kApiBoilerplate };
template <class ContextObject, BoilerplateKind boilerplate_kind>
template <class ContextObject>
class JSObjectWalkVisitor {
public:
JSObjectWalkVisitor(ContextObject* site_context, bool copying,
......@@ -7956,9 +7954,9 @@ class JSObjectWalkVisitor {
const JSObject::DeepCopyHints hints_;
};
template <class ContextObject, BoilerplateKind boilerplate_kind>
MaybeHandle<JSObject> JSObjectWalkVisitor<
ContextObject, boilerplate_kind>::StructureWalk(Handle<JSObject> object) {
template <class ContextObject>
MaybeHandle<JSObject> JSObjectWalkVisitor<ContextObject>::StructureWalk(
Handle<JSObject> object) {
Isolate* isolate = this->isolate();
bool copying = this->copying();
bool shallow = hints_ == JSObject::kObjectIsShallow;
......@@ -7978,29 +7976,8 @@ MaybeHandle<JSObject> JSObjectWalkVisitor<
Handle<JSObject> copy;
if (copying) {
if (boilerplate_kind == BoilerplateKind::kApiBoilerplate) {
if (object->IsJSFunction()) {
#ifdef DEBUG
// Ensure that it is an Api function and template_instantiations_cache
// contains an entry for function's FunctionTemplateInfo.
JSFunction* function = JSFunction::cast(*object);
CHECK(function->shared()->IsApiFunction());
FunctionTemplateInfo* data = function->shared()->get_api_func_data();
auto serial_number = handle(Smi::cast(data->serial_number()), isolate);
CHECK(serial_number->value());
auto cache = isolate->template_instantiations_cache();
int entry =
cache->FindEntry(static_cast<uint32_t>(serial_number->value()));
CHECK(entry != UnseededNumberDictionary::kNotFound);
Object* element = cache->ValueAt(entry);
CHECK_EQ(function, element);
#endif
return object;
}
} else {
// JSFunction objects are not allowed to be in normal boilerplates at all.
DCHECK(!object->IsJSFunction());
}
// JSFunction objects are not allowed to be in normal boilerplates at all.
DCHECK(!object->IsJSFunction());
Handle<AllocationSite> site_to_pass;
if (site_context()->ShouldCreateMemento(object)) {
site_to_pass = site_context()->current();
......@@ -8169,9 +8146,8 @@ MaybeHandle<JSObject> JSObjectWalkVisitor<
MaybeHandle<JSObject> JSObject::DeepWalk(
Handle<JSObject> object,
AllocationSiteCreationContext* site_context) {
JSObjectWalkVisitor<AllocationSiteCreationContext,
BoilerplateKind::kNormalBoilerplate> v(site_context,
false, kNoHints);
JSObjectWalkVisitor<AllocationSiteCreationContext> v(site_context, false,
kNoHints);
MaybeHandle<JSObject> result = v.StructureWalk(object);
Handle<JSObject> for_assert;
DCHECK(!result.ToHandle(&for_assert) || for_assert.is_identical_to(object));
......@@ -8183,30 +8159,7 @@ MaybeHandle<JSObject> JSObject::DeepCopy(
Handle<JSObject> object,
AllocationSiteUsageContext* site_context,
DeepCopyHints hints) {
JSObjectWalkVisitor<AllocationSiteUsageContext,
BoilerplateKind::kNormalBoilerplate> v(site_context, true,
hints);
MaybeHandle<JSObject> copy = v.StructureWalk(object);
Handle<JSObject> for_assert;
DCHECK(!copy.ToHandle(&for_assert) || !for_assert.is_identical_to(object));
return copy;
}
class DummyContextObject : public AllocationSiteContext {
public:
explicit DummyContextObject(Isolate* isolate)
: AllocationSiteContext(isolate) {}
bool ShouldCreateMemento(Handle<JSObject> object) { return false; }
Handle<AllocationSite> EnterNewScope() { return Handle<AllocationSite>(); }
void ExitScope(Handle<AllocationSite> site, Handle<JSObject> object) {}
};
MaybeHandle<JSObject> JSObject::DeepCopyApiBoilerplate(
Handle<JSObject> object) {
DummyContextObject dummy_context_object(object->GetIsolate());
JSObjectWalkVisitor<DummyContextObject, BoilerplateKind::kApiBoilerplate> v(
&dummy_context_object, true, kNoHints);
JSObjectWalkVisitor<AllocationSiteUsageContext> v(site_context, true, hints);
MaybeHandle<JSObject> copy = v.StructureWalk(object);
Handle<JSObject> for_assert;
DCHECK(!copy.ToHandle(&for_assert) || !for_assert.is_identical_to(object));
......
......@@ -2380,10 +2380,6 @@ class JSObject: public JSReceiver {
Handle<JSObject> object,
AllocationSiteUsageContext* site_context,
DeepCopyHints hints = kNoHints);
// Deep copies given object with special handling for JSFunctions which
// 1) must be Api functions and 2) are not copied but left as is.
MUST_USE_RESULT static MaybeHandle<JSObject> DeepCopyApiBoilerplate(
Handle<JSObject> object);
MUST_USE_RESULT static MaybeHandle<JSObject> DeepWalk(
Handle<JSObject> object,
AllocationSiteCreationContext* site_context);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment