Commit 881e9807 authored by Camillo Bruni's avatar Camillo Bruni Committed by Commit Bot

[cleanup] Move Clone and AllocationSite creation into runtime-literals.cc

Change-Id: I353d5959eef5369ae42ed7a176d6e59e94cc2d77
Reviewed-on: https://chromium-review.googlesource.com/541424Reviewed-by: 's avatarToon Verwaest <verwaest@chromium.org>
Commit-Queue: Camillo Bruni <cbruni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#46057}
parent f6bc2088
......@@ -7874,212 +7874,6 @@ Handle<Object> JSObject::FastPropertyAt(Handle<JSObject> object,
Handle<Object> raw_value(object->RawFastPropertyAt(index), isolate);
return Object::WrapForRead(isolate, raw_value, representation);
}
template <class ContextObject>
class JSObjectWalkVisitor {
public:
JSObjectWalkVisitor(ContextObject* site_context,
JSObject::DeepCopyHints hints)
: site_context_(site_context), hints_(hints) {}
MUST_USE_RESULT MaybeHandle<JSObject> StructureWalk(Handle<JSObject> object);
protected:
MUST_USE_RESULT inline MaybeHandle<JSObject> VisitElementOrProperty(
Handle<JSObject> object,
Handle<JSObject> value) {
Handle<AllocationSite> current_site = site_context()->EnterNewScope();
MaybeHandle<JSObject> copy_of_value = StructureWalk(value);
site_context()->ExitScope(current_site, value);
return copy_of_value;
}
inline ContextObject* site_context() { return site_context_; }
inline Isolate* isolate() { return site_context()->isolate(); }
private:
ContextObject* site_context_;
const JSObject::DeepCopyHints hints_;
};
template <class ContextObject>
MaybeHandle<JSObject> JSObjectWalkVisitor<ContextObject>::StructureWalk(
Handle<JSObject> object) {
Isolate* isolate = this->isolate();
bool copying = ContextObject::kCopying;
bool shallow = hints_ == JSObject::kObjectIsShallow;
if (!shallow) {
StackLimitCheck check(isolate);
if (check.HasOverflowed()) {
isolate->StackOverflow();
return MaybeHandle<JSObject>();
}
}
if (object->map()->is_deprecated()) {
JSObject::MigrateInstance(object);
}
Handle<JSObject> copy;
if (copying) {
// 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();
}
copy = isolate->factory()->CopyJSObjectWithAllocationSite(
object, site_to_pass);
} else {
copy = object;
}
DCHECK(copying || copy.is_identical_to(object));
if (shallow) return copy;
HandleScope scope(isolate);
// Deep copy own properties. Arrays only have 1 property "length".
if (!copy->IsJSArray()) {
if (copy->HasFastProperties()) {
Handle<DescriptorArray> descriptors(copy->map()->instance_descriptors());
int limit = copy->map()->NumberOfOwnDescriptors();
for (int i = 0; i < limit; i++) {
DCHECK_EQ(kField, descriptors->GetDetails(i).location());
DCHECK_EQ(kData, descriptors->GetDetails(i).kind());
FieldIndex index = FieldIndex::ForDescriptor(copy->map(), i);
if (copy->IsUnboxedDoubleField(index)) continue;
Object* raw = copy->RawFastPropertyAt(index);
if (raw->IsJSObject()) {
Handle<JSObject> value(JSObject::cast(raw), isolate);
ASSIGN_RETURN_ON_EXCEPTION(
isolate, value, VisitElementOrProperty(copy, value), JSObject);
if (copying) copy->FastPropertyAtPut(index, *value);
} else if (copying && raw->IsMutableHeapNumber()) {
DCHECK(descriptors->GetDetails(i).representation().IsDouble());
uint64_t double_value = HeapNumber::cast(raw)->value_as_bits();
Handle<HeapNumber> value = isolate->factory()->NewHeapNumber(MUTABLE);
value->set_value_as_bits(double_value);
copy->FastPropertyAtPut(index, *value);
}
}
} else {
Handle<NameDictionary> dict(NameDictionary::cast(copy->properties()));
for (int i = 0; i < dict->Capacity(); i++) {
Object* raw = dict->ValueAt(i);
if (!raw->IsJSObject()) continue;
DCHECK(dict->KeyAt(i)->IsName());
Handle<JSObject> value(JSObject::cast(raw), isolate);
ASSIGN_RETURN_ON_EXCEPTION(
isolate, value, VisitElementOrProperty(copy, value), JSObject);
if (copying) dict->ValueAtPut(i, *value);
}
}
// Assume non-arrays don't end up having elements.
if (copy->elements()->length() == 0) return copy;
}
// Deep copy own elements.
switch (copy->GetElementsKind()) {
case FAST_ELEMENTS:
case FAST_HOLEY_ELEMENTS: {
Handle<FixedArray> elements(FixedArray::cast(copy->elements()));
if (elements->map() == isolate->heap()->fixed_cow_array_map()) {
#ifdef DEBUG
for (int i = 0; i < elements->length(); i++) {
DCHECK(!elements->get(i)->IsJSObject());
}
#endif
} else {
for (int i = 0; i < elements->length(); i++) {
Object* raw = elements->get(i);
if (!raw->IsJSObject()) continue;
Handle<JSObject> value(JSObject::cast(raw), isolate);
ASSIGN_RETURN_ON_EXCEPTION(
isolate, value, VisitElementOrProperty(copy, value), JSObject);
if (copying) elements->set(i, *value);
}
}
break;
}
case DICTIONARY_ELEMENTS: {
Handle<SeededNumberDictionary> element_dictionary(
copy->element_dictionary());
int capacity = element_dictionary->Capacity();
for (int i = 0; i < capacity; i++) {
Object* raw = element_dictionary->ValueAt(i);
if (!raw->IsJSObject()) continue;
Handle<JSObject> value(JSObject::cast(raw), isolate);
ASSIGN_RETURN_ON_EXCEPTION(
isolate, value, VisitElementOrProperty(copy, value), JSObject);
if (copying) element_dictionary->ValueAtPut(i, *value);
}
break;
}
case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
UNIMPLEMENTED();
break;
case FAST_STRING_WRAPPER_ELEMENTS:
case SLOW_STRING_WRAPPER_ELEMENTS:
UNREACHABLE();
break;
#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) case TYPE##_ELEMENTS:
TYPED_ARRAYS(TYPED_ARRAY_CASE)
#undef TYPED_ARRAY_CASE
// Typed elements cannot be created using an object literal.
UNREACHABLE();
break;
case FAST_SMI_ELEMENTS:
case FAST_HOLEY_SMI_ELEMENTS:
case FAST_DOUBLE_ELEMENTS:
case FAST_HOLEY_DOUBLE_ELEMENTS:
case NO_ELEMENTS:
// No contained objects, nothing to do.
break;
}
return copy;
}
MaybeHandle<JSObject> JSObject::DeepWalk(
Handle<JSObject> object, DeprecationUpdateContext* site_context) {
JSObjectWalkVisitor<DeprecationUpdateContext> v(site_context, kNoHints);
MaybeHandle<JSObject> result = v.StructureWalk(object);
Handle<JSObject> for_assert;
DCHECK(!result.ToHandle(&for_assert) || for_assert.is_identical_to(object));
return result;
}
MaybeHandle<JSObject> JSObject::DeepWalk(
Handle<JSObject> object,
AllocationSiteCreationContext* site_context) {
JSObjectWalkVisitor<AllocationSiteCreationContext> v(site_context, kNoHints);
MaybeHandle<JSObject> result = v.StructureWalk(object);
Handle<JSObject> for_assert;
DCHECK(!result.ToHandle(&for_assert) || for_assert.is_identical_to(object));
return result;
}
MaybeHandle<JSObject> JSObject::DeepCopy(
Handle<JSObject> object,
AllocationSiteUsageContext* site_context,
DeepCopyHints hints) {
JSObjectWalkVisitor<AllocationSiteUsageContext> v(site_context, hints);
MaybeHandle<JSObject> copy = v.StructureWalk(object);
Handle<JSObject> for_assert;
DCHECK(!copy.ToHandle(&for_assert) || !for_assert.is_identical_to(object));
return copy;
}
// static
MaybeHandle<Object> JSReceiver::ToPrimitive(Handle<JSReceiver> receiver,
ToPrimitiveHint hint) {
......
......@@ -2499,19 +2499,6 @@ class JSObject: public JSReceiver {
static bool IsExtensible(Handle<JSObject> object);
// Copy object.
enum DeepCopyHints { kNoHints = 0, kObjectIsShallow = 1 };
MUST_USE_RESULT static MaybeHandle<JSObject> DeepCopy(
Handle<JSObject> object,
AllocationSiteUsageContext* site_context,
DeepCopyHints hints = kNoHints);
MUST_USE_RESULT static MaybeHandle<JSObject> DeepWalk(
Handle<JSObject> object,
AllocationSiteCreationContext* site_context);
MUST_USE_RESULT static MaybeHandle<JSObject> DeepWalk(
Handle<JSObject> object, DeprecationUpdateContext* site_context);
DECLARE_CAST(JSObject)
// Dispatched behavior.
......
This diff is collapsed.
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