Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(82)

Unified Diff: src/codegen-ia32.cc

Issue 40295: Optimizing generation of nested literals for both object and array literals. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/codegen-arm.cc ('k') | src/heap.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/codegen-ia32.cc
===================================================================
--- src/codegen-ia32.cc (revision 1467)
+++ src/codegen-ia32.cc (working copy)
@@ -32,6 +32,7 @@
#include "debug.h"
#include "scopes.h"
#include "runtime.h"
+#include "parser.h"
namespace v8 { namespace internal {
@@ -3488,7 +3489,7 @@
frame_->Push(&boilerplate);
// Clone the boilerplate object.
Result clone =
- frame_->CallRuntime(Runtime::kCloneObjectLiteralBoilerplate, 1);
+ frame_->CallRuntime(Runtime::kCloneLiteralBoilerplate, 1);
// Push the newly cloned literal object as the result.
frame_->Push(&clone);
@@ -3497,8 +3498,9 @@
switch (property->kind()) {
case ObjectLiteral::Property::CONSTANT:
break;
- case ObjectLiteral::Property::OBJECT_LITERAL:
- if (property->value()->AsObjectLiteral()->is_simple()) break;
+ case ObjectLiteral::Property::MATERIALIZED_LITERAL:
+ if (CompileTimeValue::IsCompileTimeValue(property->value())) break;
+ // else fall through.
case ObjectLiteral::Property::COMPUTED: {
Handle<Object> key(property->key()->handle());
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
@@ -3556,59 +3558,123 @@
}
+// This deferred code stub will be used for creating the boilerplate
+// by calling Runtime_CreateArrayLiteralBoilerplate.
+// Each created boilerplate is stored in the JSFunction and they are
+// therefore context dependent.
+class DeferredArrayLiteral: public DeferredCode {
+ public:
+ DeferredArrayLiteral(CodeGenerator* generator,
+ ArrayLiteral* node)
+ : DeferredCode(generator), node_(node) {
+ set_comment("[ DeferredArrayLiteral");
+ }
+
+ virtual void Generate();
+
+ private:
+ ArrayLiteral* node_;
+};
+
+
+void DeferredArrayLiteral::Generate() {
+ Result literals(generator());
+ enter()->Bind(&literals);
+ // Since the entry is undefined we call the runtime system to
+ // compute the literal.
+
+ VirtualFrame* frame = generator()->frame();
+ // Literal array (0).
+ frame->Push(&literals);
+ // Literal index (1).
+ frame->Push(Smi::FromInt(node_->literal_index()));
+ // Constant properties (2).
+ frame->Push(node_->literals());
+ Result boilerplate =
+ frame->CallRuntime(Runtime::kCreateArrayLiteralBoilerplate, 3);
+ exit_.Jump(&boilerplate);
+}
+
+
void CodeGenerator::VisitArrayLiteral(ArrayLiteral* node) {
Comment cmnt(masm_, "[ ArrayLiteral");
+ DeferredArrayLiteral* deferred = new DeferredArrayLiteral(this, node);
- // Call the runtime to create the array literal.
- frame_->Push(node->literals());
- // Load the literals array of the current function.
+ // Retrieve the literals array and check the allocated entry. Begin
+ // with a writable copy of the function of this activation in a
+ // register.
frame_->PushFunction();
Result literals = frame_->Pop();
literals.ToRegister();
- frame_->Spill(literals.reg()); // Make it writable.
+ frame_->Spill(literals.reg());
+
+ // Load the literals array of the function.
__ mov(literals.reg(),
FieldOperand(literals.reg(), JSFunction::kLiteralsOffset));
- frame_->Push(&literals);
- Result array = frame_->CallRuntime(Runtime::kCreateArrayLiteral, 2);
+ // Load the literal at the ast saved index.
+ int literal_offset =
+ FixedArray::kHeaderSize + node->literal_index() * kPointerSize;
+ Result boilerplate = allocator_->Allocate();
+ ASSERT(boilerplate.is_valid());
+ __ mov(boilerplate.reg(), FieldOperand(literals.reg(), literal_offset));
+
+ // Check whether we need to materialize the object literal boilerplate.
+ // If so, jump to the deferred code passing the literals array.
+ __ cmp(boilerplate.reg(), Factory::undefined_value());
+ deferred->enter()->Branch(equal, &literals, not_taken);
+
+ literals.Unuse();
+ // The deferred code returns the boilerplate object.
+ deferred->BindExit(&boilerplate);
+
// Push the resulting array literal on the stack.
- frame_->Push(&array);
+ frame_->Push(&boilerplate);
+ // Clone the boilerplate object.
+ Result clone =
+ frame_->CallRuntime(Runtime::kCloneLiteralBoilerplate, 1);
+ // Push the newly cloned literal object as the result.
+ frame_->Push(&clone);
+
// Generate code to set the elements in the array that are not
// literals.
for (int i = 0; i < node->values()->length(); i++) {
Expression* value = node->values()->at(i);
- // If value is literal the property value is already set in the
+ // If value is a literal the property value is already set in the
// boilerplate object.
- if (value->AsLiteral() == NULL) {
- // The property must be set by generated code.
- Load(value);
+ if (value->AsLiteral() != NULL) continue;
+ // If value is a materialized literal the property value is already set
+ // in the boilerplate object if it is simple.
+ if (CompileTimeValue::IsCompileTimeValue(value)) continue;
- // Get the property value off the stack.
- Result prop_value = frame_->Pop();
- prop_value.ToRegister();
+ // The property must be set by generated code.
+ Load(value);
- // Fetch the array literal while leaving a copy on the stack and
- // use it to get the elements array.
- frame_->Dup();
- Result elements = frame_->Pop();
- elements.ToRegister();
- frame_->Spill(elements.reg());
- // Get the elements array.
- __ mov(elements.reg(),
- FieldOperand(elements.reg(), JSObject::kElementsOffset));
+ // Get the property value off the stack.
+ Result prop_value = frame_->Pop();
+ prop_value.ToRegister();
- // Write to the indexed properties array.
- int offset = i * kPointerSize + Array::kHeaderSize;
- __ mov(FieldOperand(elements.reg(), offset), prop_value.reg());
+ // Fetch the array literal while leaving a copy on the stack and
+ // use it to get the elements array.
+ frame_->Dup();
+ Result elements = frame_->Pop();
+ elements.ToRegister();
+ frame_->Spill(elements.reg());
+ // Get the elements array.
+ __ mov(elements.reg(),
+ FieldOperand(elements.reg(), JSObject::kElementsOffset));
- // Update the write barrier for the array address.
- frame_->Spill(prop_value.reg()); // Overwritten by the write barrier.
- Result scratch = allocator_->Allocate();
- ASSERT(scratch.is_valid());
- __ RecordWrite(elements.reg(), offset, prop_value.reg(), scratch.reg());
- }
+ // Write to the indexed properties array.
+ int offset = i * kPointerSize + Array::kHeaderSize;
+ __ mov(FieldOperand(elements.reg(), offset), prop_value.reg());
+
+ // Update the write barrier for the array address.
+ frame_->Spill(prop_value.reg()); // Overwritten by the write barrier.
+ Result scratch = allocator_->Allocate();
+ ASSERT(scratch.is_valid());
+ __ RecordWrite(elements.reg(), offset, prop_value.reg(), scratch.reg());
}
}
« no previous file with comments | « src/codegen-arm.cc ('k') | src/heap.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698