| Index: src/ia32/codegen-ia32.cc
|
| ===================================================================
|
| --- src/ia32/codegen-ia32.cc (revision 3513)
|
| +++ src/ia32/codegen-ia32.cc (working copy)
|
| @@ -4269,46 +4269,10 @@
|
| }
|
|
|
|
|
| -// Materialize the object literal 'node' in the literals array
|
| -// 'literals' of the function. Leave the object boilerplate in
|
| -// 'boilerplate'.
|
| -class DeferredObjectLiteral: public DeferredCode {
|
| - public:
|
| - DeferredObjectLiteral(Register boilerplate,
|
| - Register literals,
|
| - ObjectLiteral* node)
|
| - : boilerplate_(boilerplate), literals_(literals), node_(node) {
|
| - set_comment("[ DeferredObjectLiteral");
|
| - }
|
| -
|
| - void Generate();
|
| -
|
| - private:
|
| - Register boilerplate_;
|
| - Register literals_;
|
| - ObjectLiteral* node_;
|
| -};
|
| -
|
| -
|
| -void DeferredObjectLiteral::Generate() {
|
| - // Since the entry is undefined we call the runtime system to
|
| - // compute the literal.
|
| - // Literal array (0).
|
| - __ push(literals_);
|
| - // Literal index (1).
|
| - __ push(Immediate(Smi::FromInt(node_->literal_index())));
|
| - // Constant properties (2).
|
| - __ push(Immediate(node_->constant_properties()));
|
| - __ CallRuntime(Runtime::kCreateObjectLiteralBoilerplate, 3);
|
| - if (!boilerplate_.is(eax)) __ mov(boilerplate_, eax);
|
| -}
|
| -
|
| -
|
| void CodeGenerator::VisitObjectLiteral(ObjectLiteral* node) {
|
| Comment cmnt(masm_, "[ ObjectLiteral");
|
|
|
| - // Retrieve the literals array and check the allocated entry. Begin
|
| - // with a writable copy of the function of this activation in a
|
| + // Load a writable copy of the function of this activation in a
|
| // register.
|
| frame_->PushFunction();
|
| Result literals = frame_->Pop();
|
| @@ -4318,32 +4282,18 @@
|
| // Load the literals array of the function.
|
| __ mov(literals.reg(),
|
| FieldOperand(literals.reg(), JSFunction::kLiteralsOffset));
|
| -
|
| - // Load the literal at the ast saved index.
|
| - Result boilerplate = allocator_->Allocate();
|
| - ASSERT(boilerplate.is_valid());
|
| - int literal_offset =
|
| - FixedArray::kHeaderSize + node->literal_index() * kPointerSize;
|
| - __ 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.
|
| - DeferredObjectLiteral* deferred =
|
| - new DeferredObjectLiteral(boilerplate.reg(), literals.reg(), node);
|
| - __ cmp(boilerplate.reg(), Factory::undefined_value());
|
| - deferred->Branch(equal);
|
| - deferred->BindExit();
|
| - literals.Unuse();
|
| -
|
| - // Push the boilerplate object.
|
| - frame_->Push(&boilerplate);
|
| - // Clone the boilerplate object.
|
| - Runtime::FunctionId clone_function_id = Runtime::kCloneLiteralBoilerplate;
|
| - if (node->depth() == 1) {
|
| - clone_function_id = Runtime::kCloneShallowLiteralBoilerplate;
|
| + // Literal array.
|
| + frame_->Push(&literals);
|
| + // Literal index.
|
| + frame_->Push(Smi::FromInt(node->literal_index()));
|
| + // Constant properties.
|
| + frame_->Push(node->constant_properties());
|
| + Result clone;
|
| + if (node->depth() > 1) {
|
| + clone = frame_->CallRuntime(Runtime::kCreateObjectLiteral, 3);
|
| + } else {
|
| + clone = frame_->CallRuntime(Runtime::kCreateObjectLiteralShallow, 3);
|
| }
|
| - Result clone = frame_->CallRuntime(clone_function_id, 1);
|
| - // Push the newly cloned literal object as the result.
|
| frame_->Push(&clone);
|
|
|
| for (int i = 0; i < node->properties()->length(); i++) {
|
| @@ -4403,45 +4353,10 @@
|
| }
|
|
|
|
|
| -// Materialize the array literal 'node' in the literals array 'literals'
|
| -// of the function. Leave the array boilerplate in 'boilerplate'.
|
| -class DeferredArrayLiteral: public DeferredCode {
|
| - public:
|
| - DeferredArrayLiteral(Register boilerplate,
|
| - Register literals,
|
| - ArrayLiteral* node)
|
| - : boilerplate_(boilerplate), literals_(literals), node_(node) {
|
| - set_comment("[ DeferredArrayLiteral");
|
| - }
|
| -
|
| - void Generate();
|
| -
|
| - private:
|
| - Register boilerplate_;
|
| - Register literals_;
|
| - ArrayLiteral* node_;
|
| -};
|
| -
|
| -
|
| -void DeferredArrayLiteral::Generate() {
|
| - // Since the entry is undefined we call the runtime system to
|
| - // compute the literal.
|
| - // Literal array (0).
|
| - __ push(literals_);
|
| - // Literal index (1).
|
| - __ push(Immediate(Smi::FromInt(node_->literal_index())));
|
| - // Constant properties (2).
|
| - __ push(Immediate(node_->literals()));
|
| - __ CallRuntime(Runtime::kCreateArrayLiteralBoilerplate, 3);
|
| - if (!boilerplate_.is(eax)) __ mov(boilerplate_, eax);
|
| -}
|
| -
|
| -
|
| void CodeGenerator::VisitArrayLiteral(ArrayLiteral* node) {
|
| Comment cmnt(masm_, "[ ArrayLiteral");
|
|
|
| - // Retrieve the literals array and check the allocated entry. Begin
|
| - // with a writable copy of the function of this activation in a
|
| + // Load a writable copy of the function of this activation in a
|
| // register.
|
| frame_->PushFunction();
|
| Result literals = frame_->Pop();
|
| @@ -4452,39 +4367,19 @@
|
| __ mov(literals.reg(),
|
| FieldOperand(literals.reg(), JSFunction::kLiteralsOffset));
|
|
|
| - // Load the literal at the ast saved index.
|
| - Result boilerplate = allocator_->Allocate();
|
| - ASSERT(boilerplate.is_valid());
|
| - int literal_offset =
|
| - FixedArray::kHeaderSize + node->literal_index() * kPointerSize;
|
| - __ 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.
|
| - DeferredArrayLiteral* deferred =
|
| - new DeferredArrayLiteral(boilerplate.reg(), literals.reg(), node);
|
| - __ cmp(boilerplate.reg(), Factory::undefined_value());
|
| - deferred->Branch(equal);
|
| - deferred->BindExit();
|
| - literals.Unuse();
|
| -
|
| - // Push the resulting array literal boilerplate on the stack.
|
| - frame_->Push(&boilerplate);
|
| -
|
| - // Clone the boilerplate object.
|
| + frame_->Push(&literals);
|
| + frame_->Push(Smi::FromInt(node->literal_index()));
|
| + frame_->Push(node->constant_elements());
|
| int length = node->values()->length();
|
| Result clone;
|
| - if (node->depth() == 1) {
|
| - if (length <= FastCloneShallowArrayStub::kMaximumLength) {
|
| - FastCloneShallowArrayStub stub(length);
|
| - clone = frame_->CallStub(&stub, 1);
|
| - } else {
|
| - clone = frame_->CallRuntime(Runtime::kCloneShallowLiteralBoilerplate, 1);
|
| - }
|
| + if (node->depth() > 1) {
|
| + clone = frame_->CallRuntime(Runtime::kCreateArrayLiteral, 3);
|
| + } else if (length > FastCloneShallowArrayStub::kMaximumLength) {
|
| + clone = frame_->CallRuntime(Runtime::kCreateArrayLiteralShallow, 3);
|
| } else {
|
| - clone = frame_->CallRuntime(Runtime::kCloneLiteralBoilerplate, 1);
|
| + FastCloneShallowArrayStub stub(length);
|
| + clone = frame_->CallStub(&stub, 3);
|
| }
|
| - // Push the newly cloned literal object as the result.
|
| frame_->Push(&clone);
|
|
|
| // Generate code to set the elements in the array that are not
|
| @@ -6765,14 +6660,24 @@
|
| int elements_size = (length_ > 0) ? FixedArray::SizeFor(length_) : 0;
|
| int size = JSArray::kSize + elements_size;
|
|
|
| - // Allocate both the JS array and the elements array in one big
|
| - // allocation. This avoid multiple limit checks.
|
| - Label gc;
|
| - __ AllocateInNewSpace(size, eax, ebx, ecx, &gc, TAG_OBJECT);
|
| + // Load boilerplate object into ecx and check if we need to create a
|
| + // boilerplate.
|
| + __ mov(ecx, Operand(esp, 3 * kPointerSize));
|
| + __ mov(eax, Operand(esp, 2 * kPointerSize));
|
| + ASSERT(kPointerSize == 4);
|
| + __ mov(ecx, FieldOperand(ecx,
|
| + eax,
|
| + times_2,
|
| + FixedArray::kHeaderSize));
|
| + __ cmp(ecx, Factory::undefined_value());
|
| + Label slow_case;
|
| + __ j(equal, &slow_case);
|
|
|
| - // Get the boilerplate from the stack.
|
| - __ mov(ecx, Operand(esp, 1 * kPointerSize));
|
|
|
| + // Allocate both the JS array and the elements array in one big
|
| + // allocation. This avoids multiple limit checks.
|
| + __ AllocateInNewSpace(size, eax, ebx, edx, &slow_case, TAG_OBJECT);
|
| +
|
| // Copy the JS array part.
|
| for (int i = 0; i < JSArray::kSize; i += kPointerSize) {
|
| if ((i != JSArray::kElementsOffset) || (length_ == 0)) {
|
| @@ -6795,12 +6700,12 @@
|
| }
|
| }
|
|
|
| - // Return and remove the on-stack parameter.
|
| - __ ret(1 * kPointerSize);
|
| + // Return and remove the on-stack parameters.
|
| + __ ret(3 * kPointerSize);
|
|
|
| - __ bind(&gc);
|
| - ExternalReference runtime(Runtime::kCloneShallowLiteralBoilerplate);
|
| - __ TailCallRuntime(runtime, 1, 1);
|
| + __ bind(&slow_case);
|
| + ExternalReference runtime(Runtime::kCreateArrayLiteralShallow);
|
| + __ TailCallRuntime(runtime, 3, 1);
|
| }
|
|
|
|
|
|
|