Revision: 17222
Author: [email protected]
Date: Tue Oct 15 15:35:23 2013 UTC
Log: Revert "AllocationSites for all literals"
This reverts commit r17219 due to WebKit failures.
[email protected]
[email protected]
Review URL: https://codereview.chromium.org/26539010
http://code.google.com/p/v8/source/detail?r=17222
Deleted:
/branches/bleeding_edge/src/allocation-site-scopes.cc
/branches/bleeding_edge/src/allocation-site-scopes.h
Modified:
/branches/bleeding_edge/src/flag-definitions.h
/branches/bleeding_edge/src/hydrogen.cc
/branches/bleeding_edge/src/hydrogen.h
/branches/bleeding_edge/src/objects.cc
/branches/bleeding_edge/src/objects.h
/branches/bleeding_edge/src/runtime.cc
/branches/bleeding_edge/test/mjsunit/allocation-site-info.js
/branches/bleeding_edge/tools/gyp/v8.gyp
=======================================
--- /branches/bleeding_edge/src/allocation-site-scopes.cc Tue Oct 15
14:52:58 2013 UTC
+++ /dev/null
@@ -1,108 +0,0 @@
-// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#include "allocation-site-scopes.h"
-
-namespace v8 {
-namespace internal {
-
-
-Handle<AllocationSite> AllocationSiteCreationContext::EnterNewScope() {
- Handle<AllocationSite> scope_site;
- if (top().is_null()) {
- // We are creating the top level AllocationSite as opposed to a nested
- // AllocationSite.
- InitializeTraversal(isolate()->factory()->NewAllocationSite());
- scope_site = Handle<AllocationSite>(*top(), isolate());
- if (FLAG_trace_creation_allocation_sites) {
- PrintF("*** Creating top level AllocationSite %p\n",
- static_cast<void*>(*scope_site));
- }
- } else {
- ASSERT(!current().is_null());
- scope_site = isolate()->factory()->NewAllocationSite();
- if (FLAG_trace_creation_allocation_sites) {
- PrintF("Creating nested site (top, current, new) (%p, %p, %p)\n",
- static_cast<void*>(*top()),
- static_cast<void*>(*current()),
- static_cast<void*>(*scope_site));
- }
- current()->set_nested_site(*scope_site);
- update_current_site(*scope_site);
- }
- ASSERT(!scope_site.is_null());
- return scope_site;
-}
-
-
-void AllocationSiteCreationContext::ExitScope(
- Handle<AllocationSite> scope_site,
- Handle<JSObject> object) {
- if (!object.is_null() && !object->IsFailure()) {
- bool top_level = !scope_site.is_null() &&
- top().is_identical_to(scope_site);
-
- scope_site->set_transition_info(*object);
- if (FLAG_trace_creation_allocation_sites) {
- if (top_level) {
- PrintF("*** Setting AllocationSite %p transition_info %p\n",
- static_cast<void*>(*scope_site),
- static_cast<void*>(*object));
- } else {
- PrintF("Setting AllocationSite (%p, %p) transition_info %p\n",
- static_cast<void*>(*top()),
- static_cast<void*>(*scope_site),
- static_cast<void*>(*object));
- }
- }
- }
-}
-
-
-Handle<AllocationSite> AllocationSiteUsageContext::EnterNewScope() {
- if (top().is_null()) {
- InitializeTraversal(top_site_);
- } else {
- // Advance current site
- Object* nested_site = current()->nested_site();
- // Something is wrong if we advance to the end of the list here.
- ASSERT(nested_site->IsAllocationSite());
- update_current_site(AllocationSite::cast(nested_site));
- }
- return Handle<AllocationSite>(*current(), isolate());
-}
-
-
-void AllocationSiteUsageContext::ExitScope(
- Handle<AllocationSite> scope_site,
- Handle<JSObject> object) {
- // This assert ensures that we are pointing at the right sub-object in a
- // recursive walk of a nested literal.
- ASSERT(*object == scope_site->transition_info());
-}
-
-} } // namespace v8::internal
=======================================
--- /branches/bleeding_edge/src/allocation-site-scopes.h Tue Oct 15
14:52:58 2013 UTC
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#ifndef V8_ALLOCATION_SITE_SCOPES_H_
-#define V8_ALLOCATION_SITE_SCOPES_H_
-
-#include "ast.h"
-#include "handles.h"
-#include "objects.h"
-#include "zone.h"
-
-namespace v8 {
-namespace internal {
-
-
-// AllocationSiteContext is the base class for walking and copying a nested
-// boilerplate with AllocationSite and AllocationMemento support.
-class AllocationSiteContext {
- public:
- AllocationSiteContext(Isolate* isolate, bool activated) {
- isolate_ = isolate;
- activated_ = activated;
- };
- virtual ~AllocationSiteContext() {}
-
- Handle<AllocationSite> top() { return top_; }
- Handle<AllocationSite> current() { return current_; }
-
- // If activated, then recursively create mementos
- bool activated() const { return activated_; }
-
- // Returns the AllocationSite that matches this scope.
- virtual Handle<AllocationSite> EnterNewScope() = 0;
-
- // scope_site should be the handle returned by the matching
EnterNewScope()
- virtual void ExitScope(Handle<AllocationSite> scope_site,
- Handle<JSObject> object) = 0;
-
- protected:
- void update_current_site(AllocationSite* site) {
- *(current_.location()) = site;
- }
-
- Isolate* isolate() { return isolate_; }
- void InitializeTraversal(Handle<AllocationSite> site) {
- top_ = site;
- current_ = Handle<AllocationSite>(*top_, isolate());
- }
-
- private:
- Isolate* isolate_;
- Handle<AllocationSite> top_;
- Handle<AllocationSite> current_;
- bool activated_;
-};
-
-
-// AllocationSiteCreationContext aids in the creation of AllocationSites to
-// accompany object literals.
-class AllocationSiteCreationContext : public AllocationSiteContext {
- public:
- explicit AllocationSiteCreationContext(Isolate* isolate)
- : AllocationSiteContext(isolate, true) { }
-
- virtual Handle<AllocationSite> EnterNewScope() V8_OVERRIDE;
- virtual void ExitScope(Handle<AllocationSite> site,
- Handle<JSObject> object) V8_OVERRIDE;
-};
-
-
-// AllocationSiteUsageContext aids in the creation of AllocationMementos
placed
-// behind some/all components of a copied object literal.
-class AllocationSiteUsageContext : public AllocationSiteContext {
- public:
- AllocationSiteUsageContext(Isolate* isolate, Handle<AllocationSite> site,
- bool activated)
- : AllocationSiteContext(isolate, activated),
- top_site_(site) { }
-
- virtual Handle<AllocationSite> EnterNewScope() V8_OVERRIDE;
- virtual void ExitScope(Handle<AllocationSite> site,
- Handle<JSObject> object) V8_OVERRIDE;
-
- private:
- Handle<AllocationSite> top_site_;
-};
-
-
-} } // namespace v8::internal
-
-#endif // V8_ALLOCATION_SITE_SCOPES_H_
=======================================
--- /branches/bleeding_edge/src/flag-definitions.h Tue Oct 15 14:52:58 2013
UTC
+++ /branches/bleeding_edge/src/flag-definitions.h Tue Oct 15 15:35:23 2013
UTC
@@ -806,9 +806,6 @@
// elements.cc
DEFINE_bool(trace_elements_transitions, false, "trace elements
transitions")
-DEFINE_bool(trace_creation_allocation_sites, false,
- "trace the creation of allocation sites")
-
// code-stubs.cc
DEFINE_bool(print_code_stubs, false, "print code stubs")
DEFINE_bool(test_secondary_stub_cache,
=======================================
--- /branches/bleeding_edge/src/hydrogen.cc Tue Oct 15 15:06:04 2013 UTC
+++ /branches/bleeding_edge/src/hydrogen.cc Tue Oct 15 15:35:23 2013 UTC
@@ -30,7 +30,6 @@
#include <algorithm>
#include "v8.h"
-#include "allocation-site-scopes.h"
#include "codegen.h"
#include "full-codegen.h"
#include "hashmap.h"
@@ -4299,10 +4298,7 @@
if (!boilerplate.is_null() &&
IsFastLiteral(boilerplate, kMaxFastLiteralDepth, &max_properties)) {
- AllocationSiteUsageContext usage_context(isolate(), site, false);
- usage_context.EnterNewScope();
- literal = BuildFastLiteral(boilerplate, &usage_context);
- usage_context.ExitScope(site, boilerplate);
+ literal = BuildFastLiteral(boilerplate);
} else {
NoObservableSideEffectsScope no_effects(this);
Handle<FixedArray> closure_literals(closure->literals(), isolate());
@@ -4318,9 +4314,6 @@
Add<HPushArgument>(Add<HConstant>(constant_properties));
Add<HPushArgument>(Add<HConstant>(flags));
- // TODO(mvstanton): Add a flag to turn off creation of any
- // AllocationMementos for this call: we are in crankshaft and should
have
- // learned enough about transition behavior to stop emitting mementos.
Runtime::FunctionId function_id = Runtime::kCreateObjectLiteral;
literal = Add<HCallRuntime>(isolate()->factory()->empty_string(),
Runtime::FunctionForId(function_id),
@@ -4411,48 +4404,45 @@
bool uninitialized = false;
Handle<Object> literals_cell(literals->get(expr->literal_index()),
isolate());
- Handle<JSObject> boilerplate_object;
+ Handle<Object> raw_boilerplate;
if (literals_cell->IsUndefined()) {
uninitialized = true;
- Handle<Object> raw_boilerplate =
Runtime::CreateArrayLiteralBoilerplate(
+ raw_boilerplate = Runtime::CreateArrayLiteralBoilerplate(
isolate(), literals, expr->constant_elements());
if (raw_boilerplate.is_null()) {
return Bailout(kArrayBoilerplateCreationFailed);
}
- boilerplate_object = Handle<JSObject>::cast(raw_boilerplate);
- AllocationSiteCreationContext creation_context(isolate());
- site = creation_context.EnterNewScope();
- JSObject::DeepWalk(boilerplate_object, &creation_context);
- creation_context.ExitScope(site, boilerplate_object);
+ site = isolate()->factory()->NewAllocationSite();
+ site->set_transition_info(*raw_boilerplate);
literals->set(expr->literal_index(), *site);
- if (boilerplate_object->elements()->map() ==
+ if (JSObject::cast(*raw_boilerplate)->elements()->map() ==
isolate()->heap()->fixed_cow_array_map()) {
isolate()->counters()->cow_arrays_created_runtime()->Increment();
}
} else {
ASSERT(literals_cell->IsAllocationSite());
site = Handle<AllocationSite>::cast(literals_cell);
- boilerplate_object = Handle<JSObject>(
- JSObject::cast(site->transition_info()), isolate());
+ raw_boilerplate = Handle<Object>(site->transition_info(), isolate());
}
- ASSERT(!boilerplate_object.is_null());
- ASSERT(site->SitePointsToLiteral());
+ ASSERT(!raw_boilerplate.is_null());
+ ASSERT(site->IsLiteralSite());
+ Handle<JSObject> boilerplate_object =
+ Handle<JSObject>::cast(raw_boilerplate);
ElementsKind boilerplate_elements_kind =
- boilerplate_object->GetElementsKind();
+ Handle<JSObject>::cast(boilerplate_object)->GetElementsKind();
+
+
ASSERT(AllocationSite::CanTrack(boilerplate_object->map()->instance_type()));
// Check whether to use fast or slow deep-copying for boilerplate.
int max_properties = kMaxFastLiteralProperties;
if (IsFastLiteral(boilerplate_object,
kMaxFastLiteralDepth,
&max_properties)) {
- AllocationSiteUsageContext usage_context(isolate(), site, false);
- usage_context.EnterNewScope();
- literal = BuildFastLiteral(boilerplate_object, &usage_context);
- usage_context.ExitScope(site, boilerplate_object);
+ literal = BuildFastLiteral(boilerplate_object);
} else {
NoObservableSideEffectsScope no_effects(this);
// Boilerplate already exists and constant elements are never accessed,
@@ -4464,9 +4454,6 @@
Add<HPushArgument>(Add<HConstant>(literal_index));
Add<HPushArgument>(Add<HConstant>(constants));
- // TODO(mvstanton): Consider a flag to turn off creation of any
- // AllocationMementos for this call: we are in crankshaft and should
have
- // learned enough about transition behavior to stop emitting mementos.
Runtime::FunctionId function_id = (expr->depth() > 1)
? Runtime::kCreateArrayLiteral :
Runtime::kCreateArrayLiteralShallow;
literal = Add<HCallRuntime>(isolate()->factory()->empty_string(),
@@ -8355,8 +8342,7 @@
HInstruction* HOptimizedGraphBuilder::BuildFastLiteral(
- Handle<JSObject> boilerplate_object,
- AllocationSiteContext* site_context) {
+ Handle<JSObject> boilerplate_object) {
NoObservableSideEffectsScope no_effects(this);
InstanceType instance_type = boilerplate_object->map()->instance_type();
ASSERT(instance_type == JS_ARRAY_TYPE || instance_type ==
JS_OBJECT_TYPE);
@@ -8388,15 +8374,15 @@
}
BuildInitElementsInObjectHeader(boilerplate_object, object,
object_elements);
+
// Copy object elements if non-COW.
if (object_elements != NULL) {
- BuildEmitElements(boilerplate_object, elements, object_elements,
- site_context);
+ BuildEmitElements(boilerplate_object, elements, object_elements);
}
// Copy in-object properties.
if (boilerplate_object->map()->NumberOfFields() != 0) {
- BuildEmitInObjectProperties(boilerplate_object, object, site_context);
+ BuildEmitInObjectProperties(boilerplate_object, object);
}
return object;
}
@@ -8448,8 +8434,7 @@
void HOptimizedGraphBuilder::BuildEmitInObjectProperties(
Handle<JSObject> boilerplate_object,
- HInstruction* object,
- AllocationSiteContext* site_context) {
+ HInstruction* object) {
Handle<DescriptorArray> descriptors(
boilerplate_object->map()->instance_descriptors());
int limit = boilerplate_object->map()->NumberOfOwnDescriptors();
@@ -8473,10 +8458,7 @@
if (value->IsJSObject()) {
Handle<JSObject> value_object = Handle<JSObject>::cast(value);
- Handle<AllocationSite> current_site = site_context->EnterNewScope();
- HInstruction* result =
- BuildFastLiteral(value_object, site_context);
- site_context->ExitScope(current_site, value_object);
+ HInstruction* result = BuildFastLiteral(value_object);
Add<HStoreNamedField>(object, access, result);
} else {
Representation representation = details.representation();
@@ -8485,12 +8467,6 @@
if (representation.IsDouble()) {
// Allocate a HeapNumber box and store the value into it.
HValue* heap_number_constant = Add<HConstant>(HeapNumber::kSize);
- // TODO(mvstanton): This heap number alloc does not have a
corresponding
- // AllocationSite. That is okay because
- // 1) it's a child object of another object with a valid
allocation site
- // 2) we can just use the mode of the parent object for pretenuring
- // The todo is replace GetPretenureMode() with
- // site_context->top()->GetPretenureMode().
HInstruction* double_box =
Add<HAllocate>(heap_number_constant, HType::HeapNumber(),
isolate()->heap()->GetPretenureMode(), HEAP_NUMBER_TYPE);
@@ -8520,8 +8496,7 @@
void HOptimizedGraphBuilder::BuildEmitElements(
Handle<JSObject> boilerplate_object,
Handle<FixedArrayBase> elements,
- HValue* object_elements,
- AllocationSiteContext* site_context) {
+ HValue* object_elements) {
ElementsKind kind = boilerplate_object->map()->elements_kind();
int elements_length = elements->length();
HValue* object_elements_length = Add<HConstant>(elements_length);
@@ -8531,8 +8506,7 @@
if (elements->IsFixedDoubleArray()) {
BuildEmitFixedDoubleArray(elements, kind, object_elements);
} else if (elements->IsFixedArray()) {
- BuildEmitFixedArray(elements, kind, object_elements,
- site_context);
+ BuildEmitFixedArray(elements, kind, object_elements);
} else {
UNREACHABLE();
}
@@ -8561,8 +8535,7 @@
void HOptimizedGraphBuilder::BuildEmitFixedArray(
Handle<FixedArrayBase> elements,
ElementsKind kind,
- HValue* object_elements,
- AllocationSiteContext* site_context) {
+ HValue* object_elements) {
HInstruction* boilerplate_elements = Add<HConstant>(elements);
int elements_length = elements->length();
Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements);
@@ -8571,10 +8544,7 @@
HValue* key_constant = Add<HConstant>(i);
if (value->IsJSObject()) {
Handle<JSObject> value_object = Handle<JSObject>::cast(value);
- Handle<AllocationSite> current_site = site_context->EnterNewScope();
- HInstruction* result =
- BuildFastLiteral(value_object, site_context);
- site_context->ExitScope(current_site, value_object);
+ HInstruction* result = BuildFastLiteral(value_object);
Add<HStoreKeyed>(object_elements, key_constant, result, kind);
} else {
HInstruction* value_instruction =
=======================================
--- /branches/bleeding_edge/src/hydrogen.h Tue Oct 15 15:06:04 2013 UTC
+++ /branches/bleeding_edge/src/hydrogen.h Tue Oct 15 15:35:23 2013 UTC
@@ -2248,8 +2248,7 @@
HInstruction* BuildThisFunction();
- HInstruction* BuildFastLiteral(Handle<JSObject> boilerplate_object,
- AllocationSiteContext* site_context);
+ HInstruction* BuildFastLiteral(Handle<JSObject> boilerplate_object);
void BuildEmitObjectHeader(Handle<JSObject> boilerplate_object,
HInstruction* object);
@@ -2259,13 +2258,11 @@
HInstruction* object_elements);
void BuildEmitInObjectProperties(Handle<JSObject> boilerplate_object,
- HInstruction* object,
- AllocationSiteContext* site_context);
+ HInstruction* object);
void BuildEmitElements(Handle<JSObject> boilerplate_object,
Handle<FixedArrayBase> elements,
- HValue* object_elements,
- AllocationSiteContext* site_context);
+ HValue* object_elements);
void BuildEmitFixedDoubleArray(Handle<FixedArrayBase> elements,
ElementsKind kind,
@@ -2273,8 +2270,7 @@
void BuildEmitFixedArray(Handle<FixedArrayBase> elements,
ElementsKind kind,
- HValue* object_elements,
- AllocationSiteContext* site_context);
+ HValue* object_elements);
void AddCheckPrototypeMaps(Handle<JSObject> holder,
Handle<Map> receiver_map);
=======================================
--- /branches/bleeding_edge/src/objects.cc Tue Oct 15 14:52:58 2013 UTC
+++ /branches/bleeding_edge/src/objects.cc Tue Oct 15 15:35:23 2013 UTC
@@ -28,7 +28,6 @@
#include "v8.h"
#include "accessors.h"
-#include "allocation-site-scopes.h"
#include "api.h"
#include "arguments.h"
#include "bootstrapper.h"
@@ -5615,14 +5614,6 @@
return heap->undefined_value();
}
-
-Handle<JSObject> JSObject::Copy(Handle<JSObject> object,
- Handle<AllocationSite> site) {
- Isolate* isolate = object->GetIsolate();
- CALL_HEAP_FUNCTION(isolate,
- isolate->heap()->CopyJSObject(*object, *site),
JSObject);
-}
-
Handle<JSObject> JSObject::Copy(Handle<JSObject> object) {
Isolate* isolate = object->GetIsolate();
@@ -5633,93 +5624,45 @@
class JSObjectWalkVisitor {
public:
- explicit JSObjectWalkVisitor(AllocationSiteContext* site_context) :
- site_context_(site_context) {}
+ explicit JSObjectWalkVisitor() {}
virtual ~JSObjectWalkVisitor() {}
Handle<JSObject> Visit(Handle<JSObject> object) {
return StructureWalk(object);
}
+ // Returns true if the visitor is a copying visitor.
virtual bool is_copying() = 0;
protected:
Handle<JSObject> StructureWalk(Handle<JSObject> object);
- // The returned handle will be used for the object in all subsequent
usages.
- // This allows VisitObject to make a copy of the object if desired.
+ // The returned handle should point to a new object if the visitor is a
+ // copying visitor, otherwise it should be the same as the input object.
virtual Handle<JSObject> VisitObject(Handle<JSObject> object) = 0;
+
+ // The returned handle should point to a new value if the visitor is a
+ // copying visitor, otherwise it should be the same as the input value.
virtual Handle<JSObject> VisitElementOrProperty(Handle<JSObject> object,
Handle<JSObject> value)
= 0;
-
- AllocationSiteContext* site_context() { return site_context_; }
-
- private:
- AllocationSiteContext* site_context_;
};
class JSObjectCopyVisitor: public JSObjectWalkVisitor {
public:
- explicit JSObjectCopyVisitor(AllocationSiteContext* site_context)
- : JSObjectWalkVisitor(site_context) {}
+ explicit JSObjectCopyVisitor() {}
virtual bool is_copying() V8_OVERRIDE { return true; }
- // The returned handle will be used for the object in all
- // subsequent usages. This allows VisitObject to make a copy
- // of the object if desired.
- virtual Handle<JSObject> VisitObject(Handle<JSObject> object)
V8_OVERRIDE {
- // Only create a memento if
- // 1) we have a JSArray, and
- // 2) the elements kind is palatable
- // 3) allow_mementos is true
- Handle<JSObject> copy;
- if (site_context()->activated() &&
- AllocationSite::CanTrack(object->map()->instance_type()) &&
- AllocationSite::GetMode(object->GetElementsKind()) ==
- TRACK_ALLOCATION_SITE) {
- copy = JSObject::Copy(object, site_context()->current());
- } else {
- copy = JSObject::Copy(object);
- }
-
- return copy;
- }
-
- virtual Handle<JSObject> VisitElementOrProperty(
- Handle<JSObject> object,
- Handle<JSObject> value) V8_OVERRIDE {
- Handle<AllocationSite> current_site = site_context()->EnterNewScope();
- Handle<JSObject> copy_of_value = StructureWalk(value);
- site_context()->ExitScope(current_site, value);
- return copy_of_value;
- }
-};
-
-
-class JSObjectCreateAllocationSitesVisitor: public JSObjectWalkVisitor {
- public:
- explicit JSObjectCreateAllocationSitesVisitor(
- AllocationSiteContext* site_context)
- : JSObjectWalkVisitor(site_context) {}
-
- virtual bool is_copying() V8_OVERRIDE { return false; }
-
- // The returned handle will be used for the object in all
- // subsequent usages. This allows VisitObject to make a copy
- // of the object if desired.
+ protected:
virtual Handle<JSObject> VisitObject(Handle<JSObject> object)
V8_OVERRIDE {
- return object;
+ return JSObject::Copy(object);
}
virtual Handle<JSObject> VisitElementOrProperty(
Handle<JSObject> object,
Handle<JSObject> value) V8_OVERRIDE {
- Handle<AllocationSite> current_site = site_context()->EnterNewScope();
- value = StructureWalk(value);
- site_context()->ExitScope(current_site, value);
- return value;
+ return StructureWalk(value);
}
};
@@ -5866,18 +5809,8 @@
}
-Handle<JSObject> JSObject::DeepWalk(Handle<JSObject> object,
- AllocationSiteContext* site_context) {
- JSObjectCreateAllocationSitesVisitor v(site_context);
- Handle<JSObject> copy = v.Visit(object);
- ASSERT(!v.is_copying() && copy.is_identical_to(object));
- return copy;
-}
-
-
-Handle<JSObject> JSObject::DeepCopy(Handle<JSObject> object,
- AllocationSiteContext* site_context) {
- JSObjectCopyVisitor v(site_context);
+Handle<JSObject> JSObject::DeepCopy(Handle<JSObject> object) {
+ JSObjectCopyVisitor v;
Handle<JSObject> copy = v.Visit(object);
ASSERT(v.is_copying() && !copy.is_identical_to(object));
return copy;
@@ -12638,20 +12571,6 @@
CALL_HEAP_FUNCTION_VOID(object->GetIsolate(),
object->TransitionElementsKind(to_kind));
}
-
-
-bool AllocationSite::IsNestedSite() {
- ASSERT(FLAG_trace_track_allocation_sites);
- Object* current = GetHeap()->allocation_sites_list();
- while (current != NULL && current->IsAllocationSite()) {
- AllocationSite* current_site = AllocationSite::cast(current);
- if (current_site->nested_site() == this) {
- return true;
- }
- current = current_site->weak_next();
- }
- return false;
-}
MaybeObject* JSObject::UpdateAllocationSite(ElementsKind to_kind) {
@@ -12666,8 +12585,7 @@
// Walk through to the Allocation Site
AllocationSite* site = memento->GetAllocationSite();
- if (site->SitePointsToLiteral() &&
- site->transition_info()->IsJSArray()) {
+ if (site->IsLiteralSite()) {
JSArray* transition_info = JSArray::cast(site->transition_info());
ElementsKind kind = transition_info->GetElementsKind();
// if kind is holey ensure that to_kind is as well.
@@ -12681,11 +12599,9 @@
CHECK(transition_info->length()->ToArrayIndex(&length));
if (length <= AllocationSite::kMaximumArrayBytesToPretransition) {
if (FLAG_trace_track_allocation_sites) {
- bool is_nested = site->IsNestedSite();
PrintF(
- "AllocationSite: JSArray %p boilerplate %s updated %s->%s\n",
+ "AllocationSite: JSArray %p boilerplate updated %s->%s\n",
reinterpret_cast<void*>(this),
- is_nested ? "(nested)" : "",
ElementsKindToString(kind),
ElementsKindToString(to_kind));
}
=======================================
--- /branches/bleeding_edge/src/objects.h Tue Oct 15 14:52:58 2013 UTC
+++ /branches/bleeding_edge/src/objects.h Tue Oct 15 15:35:23 2013 UTC
@@ -865,9 +865,8 @@
inline void set_##name(type* value, \
WriteBarrierMode mode = UPDATE_WRITE_BARRIER); \
+
class AccessorPair;
-class AllocationSite;
-class AllocationSiteContext;
class DictionaryElementsAccessor;
class ElementsAccessor;
class Failure;
@@ -2545,13 +2544,8 @@
MUST_USE_RESULT MaybeObject* SetObserved(Isolate* isolate);
// Copy object.
- static Handle<JSObject> Copy(Handle<JSObject> object,
- Handle<AllocationSite> site);
static Handle<JSObject> Copy(Handle<JSObject> object);
- static Handle<JSObject> DeepCopy(Handle<JSObject> object,
- AllocationSiteContext* site_context);
- static Handle<JSObject> DeepWalk(Handle<JSObject> object,
- AllocationSiteContext* site_context);
+ static Handle<JSObject> DeepCopy(Handle<JSObject> object);
// Casting.
static inline JSObject* cast(Object* obj);
@@ -8011,15 +8005,8 @@
inline void Initialize();
- bool HasNestedSites() {
- return nested_site()->IsAllocationSite();
- }
-
- // This method is expensive, it should only be called for reporting.
- bool IsNestedSite();
-
ElementsKind GetElementsKind() {
- ASSERT(!SitePointsToLiteral());
+ ASSERT(!IsLiteralSite());
return
static_cast<ElementsKind>(Smi::cast(transition_info())->value());
}
@@ -8027,11 +8014,11 @@
set_transition_info(Smi::FromInt(static_cast<int>(kind)));
}
- bool SitePointsToLiteral() {
+ bool IsLiteralSite() {
// If transition_info is a smi, then it represents an ElementsKind
// for a constructed array. Otherwise, it must be a boilerplate
- // for an object or array literal.
- return transition_info()->IsJSArray() ||
transition_info()->IsJSObject();
+ // for an array literal
+ return transition_info()->IsJSArray();
}
DECLARE_PRINTER(AllocationSite)
=======================================
--- /branches/bleeding_edge/src/runtime.cc Tue Oct 15 14:52:58 2013 UTC
+++ /branches/bleeding_edge/src/runtime.cc Tue Oct 15 15:35:23 2013 UTC
@@ -31,7 +31,6 @@
#include "v8.h"
#include "accessors.h"
-#include "allocation-site-scopes.h"
#include "api.h"
#include "arguments.h"
#include "bootstrapper.h"
@@ -489,34 +488,25 @@
// Check if boilerplate exists. If not, create it first.
Handle<Object> literal_site(literals->get(literals_index), isolate);
Handle<AllocationSite> site;
- Handle<JSObject> boilerplate;
+ Handle<Object> boilerplate;
if (*literal_site == isolate->heap()->undefined_value()) {
- Handle<Object> raw_boilerplate = CreateObjectLiteralBoilerplate(
- isolate,
- literals,
- constant_properties,
- should_have_fast_elements,
- has_function_literal);
- RETURN_IF_EMPTY_HANDLE(isolate, raw_boilerplate);
- boilerplate = Handle<JSObject>::cast(raw_boilerplate);
-
- AllocationSiteCreationContext creation_context(isolate);
- site = creation_context.EnterNewScope();
- JSObject::DeepWalk(boilerplate, &creation_context);
- creation_context.ExitScope(site, boilerplate);
+ boilerplate = CreateObjectLiteralBoilerplate(isolate,
+ literals,
+ constant_properties,
+ should_have_fast_elements,
+ has_function_literal);
+ RETURN_IF_EMPTY_HANDLE(isolate, boilerplate);
+ site = isolate->factory()->NewAllocationSite();
+ site->set_transition_info(*boilerplate);
// Update the functions literal and return the boilerplate.
literals->set(literals_index, *site);
} else {
site = Handle<AllocationSite>::cast(literal_site);
- boilerplate = Handle<JSObject>(JSObject::cast(site->transition_info()),
- isolate);
+ boilerplate =
Handle<JSObject>(JSObject::cast(site->transition_info()));
}
- AllocationSiteUsageContext usage_context(isolate, site, true);
- usage_context.EnterNewScope();
- Handle<Object> copy = JSObject::DeepCopy(boilerplate, &usage_context);
- usage_context.ExitScope(site, boilerplate);
+ Handle<Object> copy =
JSObject::DeepCopy(Handle<JSObject>::cast(boilerplate));
RETURN_IF_EMPTY_HANDLE(isolate, copy);
return *copy;
}
@@ -534,13 +524,12 @@
ASSERT(*elements != isolate->heap()->empty_fixed_array());
Handle<Object> boilerplate =
Runtime::CreateArrayLiteralBoilerplate(isolate, literals,
elements);
- if (boilerplate.is_null()) return Handle<AllocationSite>::null();
-
- AllocationSiteCreationContext creation_context(isolate);
- site = creation_context.EnterNewScope();
- JSObject::DeepWalk(Handle<JSObject>::cast(boilerplate),
&creation_context);
- creation_context.ExitScope(site, Handle<JSObject>::cast(boilerplate));
-
+ if (boilerplate.is_null()) {
+ ASSERT(site.is_null());
+ return site;
+ }
+ site = isolate->factory()->NewAllocationSite();
+ site->set_transition_info(*boilerplate);
literals->set(literals_index, *site);
} else {
site = Handle<AllocationSite>::cast(literal_site);
@@ -562,10 +551,7 @@
RETURN_IF_EMPTY_HANDLE(isolate, site);
Handle<JSObject> boilerplate(JSObject::cast(site->transition_info()));
- AllocationSiteUsageContext usage_context(isolate, site, true);
- usage_context.EnterNewScope();
- Handle<JSObject> copy = JSObject::DeepCopy(boilerplate, &usage_context);
- usage_context.ExitScope(site, boilerplate);
+ Handle<JSObject> copy = JSObject::DeepCopy(boilerplate);
RETURN_IF_EMPTY_HANDLE(isolate, copy);
return *copy;
}
@@ -588,8 +574,9 @@
isolate->counters()->cow_arrays_created_runtime()->Increment();
}
- if (AllocationSite::GetMode(boilerplate->GetElementsKind()) ==
- TRACK_ALLOCATION_SITE) {
+ AllocationSiteMode mode = AllocationSite::GetMode(
+ boilerplate->GetElementsKind());
+ if (mode == TRACK_ALLOCATION_SITE) {
return isolate->heap()->CopyJSObject(boilerplate, *site);
}
@@ -14698,7 +14685,7 @@
Handle<Cell> cell = Handle<Cell>::cast(type_info);
Handle<AllocationSite> site = Handle<AllocationSite>(
AllocationSite::cast(cell->value()), isolate);
- ASSERT(!site->SitePointsToLiteral());
+ ASSERT(!site->IsLiteralSite());
ElementsKind to_kind = site->GetElementsKind();
if (holey && !IsFastHoleyElementsKind(to_kind)) {
to_kind = GetHoleyElementsKind(to_kind);
=======================================
--- /branches/bleeding_edge/test/mjsunit/allocation-site-info.js Tue Oct 15
14:52:58 2013 UTC
+++ /branches/bleeding_edge/test/mjsunit/allocation-site-info.js Tue Oct 15
15:35:23 2013 UTC
@@ -383,114 +383,4 @@
instanceof_check(realmBArray);
assertUnoptimized(instanceof_check);
-
- // Case: make sure nested arrays benefit from allocation site feedback as
- // well.
- (function() {
- // Make sure we handle nested arrays
- function get_nested_literal() {
- var literal = [[1,2,3,4], [2], [3]];
- return literal;
- }
-
- obj = get_nested_literal();
- assertKind(elements_kind.fast, obj);
- obj[0][0] = 3.5;
- obj[2][0] = "hello";
- obj = get_nested_literal();
- assertKind(elements_kind.fast_double, obj[0]);
- assertKind(elements_kind.fast_smi_only, obj[1]);
- assertKind(elements_kind.fast, obj[2]);
-
- // A more complex nested literal case.
- function get_deep_nested_literal() {
- var literal = [[1], [[2], "hello"], 3, [4]];
- return literal;
- }
-
- obj = get_deep_nested_literal();
- assertKind(elements_kind.fast_smi_only, obj[1][0]);
- obj[0][0] = 3.5;
- obj[1][0][0] = "goodbye";
- assertKind(elements_kind.fast_double, obj[0]);
- assertKind(elements_kind.fast, obj[1][0]);
-
- obj = get_deep_nested_literal();
- assertKind(elements_kind.fast_double, obj[0]);
- assertKind(elements_kind.fast, obj[1][0]);
- })();
-
-
- // Make sure object literals with array fields benefit from the type
feedback
- // that allocation mementos provide.
- (function() {
- // A literal in an object
- function get_object_literal() {
- var literal = {
- array: [1,2,3],
- data: 3.5
- };
- return literal;
- }
-
- obj = get_object_literal();
- assertKind(elements_kind.fast_smi_only, obj.array);
- obj.array[1] = 3.5;
- assertKind(elements_kind.fast_double, obj.array);
- obj = get_object_literal();
- assertKind(elements_kind.fast_double, obj.array);
-
- function get_nested_object_literal() {
- var literal = {
- array: [[1],[2],[3]],
- data: 3.5
- };
- return literal;
- }
-
- obj = get_nested_object_literal();
- assertKind(elements_kind.fast, obj.array);
- assertKind(elements_kind.fast_smi_only, obj.array[1]);
- obj.array[1][0] = 3.5;
- assertKind(elements_kind.fast_double, obj.array[1]);
- obj = get_nested_object_literal();
- assertKind(elements_kind.fast_double, obj.array[1]);
-
- %OptimizeFunctionOnNextCall(get_nested_object_literal);
- get_nested_object_literal();
- obj = get_nested_object_literal();
- assertKind(elements_kind.fast_double, obj.array[1]);
-
- // Make sure we handle nested arrays
- function get_nested_literal() {
- var literal = [[1,2,3,4], [2], [3]];
- return literal;
- }
-
- obj = get_nested_literal();
- assertKind(elements_kind.fast, obj);
- obj[0][0] = 3.5;
- obj[2][0] = "hello";
- obj = get_nested_literal();
- assertKind(elements_kind.fast_double, obj[0]);
- assertKind(elements_kind.fast_smi_only, obj[1]);
- assertKind(elements_kind.fast, obj[2]);
-
- // A more complex nested literal case.
- function get_deep_nested_literal() {
- var literal = [[1], [[2], "hello"], 3, [4]];
- return literal;
- }
-
- obj = get_deep_nested_literal();
- assertKind(elements_kind.fast_smi_only, obj[1][0]);
- obj[0][0] = 3.5;
- obj[1][0][0] = "goodbye";
- assertKind(elements_kind.fast_double, obj[0]);
- assertKind(elements_kind.fast, obj[1][0]);
-
- obj = get_deep_nested_literal();
- assertKind(elements_kind.fast_double, obj[0]);
- assertKind(elements_kind.fast, obj[1][0]);
- })();
}
=======================================
--- /branches/bleeding_edge/tools/gyp/v8.gyp Tue Oct 15 14:52:58 2013 UTC
+++ /branches/bleeding_edge/tools/gyp/v8.gyp Tue Oct 15 15:35:23 2013 UTC
@@ -209,8 +209,6 @@
'../../src/accessors.h',
'../../src/allocation.cc',
'../../src/allocation.h',
- '../../src/allocation-site-scopes.cc',
- '../../src/allocation-site-scopes.h',
'../../src/api.cc',
'../../src/api.h',
'../../src/apiutils.h',
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.