From: mstarzinger@chromium.org Date: Thu, 1 Dec 2011 14:12:30 +0000 (+0000) Subject: MIPS: Implement code stub for object literal creation. X-Git-Tag: upstream/4.7.83~17808 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=75a8165950d16df50781d64d73f71dc7815541a4;p=platform%2Fupstream%2Fv8.git MIPS: Implement code stub for object literal creation. Port r10056 (ffa6eedd8). Original commit message: This just ports r10036 to the ARM codegenerator. Please see the original revision for a detailed description. BUG= TEST= Review URL: http://codereview.chromium.org/8747011 Patch from Daniel Kalmar . git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@10124 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/mips/code-stubs-mips.cc b/src/mips/code-stubs-mips.cc index bf1cf7d..5144832 100644 --- a/src/mips/code-stubs-mips.cc +++ b/src/mips/code-stubs-mips.cc @@ -343,6 +343,51 @@ void FastCloneShallowArrayStub::Generate(MacroAssembler* masm) { } +void FastCloneShallowObjectStub::Generate(MacroAssembler* masm) { + // Stack layout on entry: + // + // [sp]: object literal flags. + // [sp + kPointerSize]: constant properties. + // [sp + (2 * kPointerSize)]: literal index. + // [sp + (3 * kPointerSize)]: literals array. + + // Load boilerplate object into a3 and check if we need to create a + // boilerplate. + Label slow_case; + __ lw(a3, MemOperand(sp, 3 * kPointerSize)); + __ lw(a0, MemOperand(sp, 2 * kPointerSize)); + __ Addu(a3, a3, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); + __ sll(t0, a0, kPointerSizeLog2 - kSmiTagSize); + __ Addu(a3, t0, a3); + __ lw(a3, MemOperand(a3)); + __ LoadRoot(t0, Heap::kUndefinedValueRootIndex); + __ Branch(&slow_case, eq, a3, Operand(t0)); + + // Check that the boilerplate contains only fast properties and we can + // statically determine the instance size. + int size = JSObject::kHeaderSize + length_ * kPointerSize; + __ lw(a0, FieldMemOperand(a3, HeapObject::kMapOffset)); + __ lbu(a0, FieldMemOperand(a0, Map::kInstanceSizeOffset)); + __ Branch(&slow_case, ne, a0, Operand(size >> kPointerSizeLog2)); + + // Allocate the JS object and copy header together with all in-object + // properties from the boilerplate. + __ AllocateInNewSpace(size, a0, a1, a2, &slow_case, TAG_OBJECT); + for (int i = 0; i < size; i += kPointerSize) { + __ lw(a1, FieldMemOperand(a3, i)); + __ sw(a1, FieldMemOperand(a0, i)); + } + + // Return and remove the on-stack parameters. + __ Drop(4); + __ Ret(USE_DELAY_SLOT); + __ mov(v0, a0); + + __ bind(&slow_case); + __ TailCallRuntime(Runtime::kCreateObjectLiteralShallow, 4, 1); +} + + // Takes a Smi and converts to an IEEE 64 bit floating point value in two // registers. The format is 1 sign bit, 11 exponent bits (biased 1023) and // 52 fraction bits (20 in the first word, 32 in the second). Zeros is a diff --git a/src/mips/full-codegen-mips.cc b/src/mips/full-codegen-mips.cc index 201e6b8..4c81d42 100644 --- a/src/mips/full-codegen-mips.cc +++ b/src/mips/full-codegen-mips.cc @@ -1424,10 +1424,11 @@ void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { Comment cmnt(masm_, "[ ObjectLiteral"); + Handle constant_properties = expr->constant_properties(); __ lw(a3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); __ lw(a3, FieldMemOperand(a3, JSFunction::kLiteralsOffset)); __ li(a2, Operand(Smi::FromInt(expr->literal_index()))); - __ li(a1, Operand(expr->constant_properties())); + __ li(a1, Operand(constant_properties)); int flags = expr->fast_elements() ? ObjectLiteral::kFastElements : ObjectLiteral::kNoFlags; @@ -1436,10 +1437,15 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { : ObjectLiteral::kNoFlags; __ li(a0, Operand(Smi::FromInt(flags))); __ Push(a3, a2, a1, a0); + int properties_count = constant_properties->length() / 2; if (expr->depth() > 1) { __ CallRuntime(Runtime::kCreateObjectLiteral, 4); - } else { + } else if (flags != ObjectLiteral::kFastElements || + properties_count > FastCloneShallowObjectStub::kMaximumClonedProperties) { __ CallRuntime(Runtime::kCreateObjectLiteralShallow, 4); + } else { + FastCloneShallowObjectStub stub(properties_count); + __ CallStub(&stub); } // If result_saved is true the result is on top of the stack. If diff --git a/src/mips/lithium-codegen-mips.cc b/src/mips/lithium-codegen-mips.cc index 32e7dc7..db84370 100644 --- a/src/mips/lithium-codegen-mips.cc +++ b/src/mips/lithium-codegen-mips.cc @@ -4176,18 +4176,30 @@ void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) { void LCodeGen::DoObjectLiteral(LObjectLiteral* instr) { ASSERT(ToRegister(instr->result()).is(v0)); + + Handle constant_properties = + instr->hydrogen()->constant_properties(); + __ lw(t0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); __ lw(t0, FieldMemOperand(t0, JSFunction::kLiteralsOffset)); __ li(a3, Operand(Smi::FromInt(instr->hydrogen()->literal_index()))); - __ li(a2, Operand(instr->hydrogen()->constant_properties())); - __ li(a1, Operand(Smi::FromInt(instr->hydrogen()->fast_elements() ? 1 : 0))); + __ li(a2, Operand(constant_properties)); + int flags = instr->hydrogen()->fast_elements() + ? ObjectLiteral::kFastElements + : ObjectLiteral::kNoFlags; + __ li(a1, Operand(Smi::FromInt(flags))); __ Push(t0, a3, a2, a1); // Pick the right runtime function to call. + int properties_count = constant_properties->length() / 2; if (instr->hydrogen()->depth() > 1) { CallRuntime(Runtime::kCreateObjectLiteral, 4, instr); - } else { + } else if (flags != ObjectLiteral::kFastElements || + properties_count > FastCloneShallowObjectStub::kMaximumClonedProperties) { CallRuntime(Runtime::kCreateObjectLiteralShallow, 4, instr); + } else { + FastCloneShallowObjectStub stub(properties_count); + CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); } }