From ce3345123c683017f7648cf6cc9992e1ec9f79b4 Mon Sep 17 00:00:00 2001 From: "hpayer@chromium.org" Date: Fri, 3 May 2013 10:36:16 +0000 Subject: [PATCH] Pretenure ASCII cons string in high promotion mode. BUG= Review URL: https://codereview.chromium.org/14451003 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@14540 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/arm/code-stubs-arm.cc | 31 +++++++++++++++++++++++++++++++ src/arm/macro-assembler-arm.cc | 30 ++++++++++++++++++++++++++++-- src/assembler.cc | 7 +++++++ src/assembler.h | 2 ++ src/heap.cc | 6 ++++-- src/heap.h | 14 ++++++++++++-- src/ia32/code-stubs-ia32.cc | 29 ++++++++++++++++++++++++++++- src/ia32/macro-assembler-ia32.cc | 28 +++++++++++++++++++++++++--- src/runtime.cc | 13 +++++++++---- src/serialize.cc | 7 ++++++- src/x64/code-stubs-x64.cc | 31 ++++++++++++++++++++++++++++++- src/x64/macro-assembler-x64.cc | 30 +++++++++++++++++++++++++++--- 12 files changed, 209 insertions(+), 19 deletions(-) diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc index e61cce5..23da69c 100644 --- a/src/arm/code-stubs-arm.cc +++ b/src/arm/code-stubs-arm.cc @@ -5958,8 +5958,36 @@ void StringAddStub::Generate(MacroAssembler* masm) { __ AllocateAsciiConsString(r7, r6, r4, r5, &call_runtime); __ bind(&allocated); // Fill the fields of the cons string. + Label skip_write_barrier, after_writing; + ExternalReference high_promotion_mode = ExternalReference:: + new_space_high_promotion_mode_active_address(masm->isolate()); + __ mov(r4, Operand(high_promotion_mode)); + __ ldr(r4, MemOperand(r4, 0)); + __ cmp(r4, Operand::Zero()); + __ b(eq, &skip_write_barrier); + + __ str(r0, FieldMemOperand(r7, ConsString::kFirstOffset)); + __ RecordWriteField(r7, + ConsString::kFirstOffset, + r0, + r4, + kLRHasNotBeenSaved, + kDontSaveFPRegs); + __ str(r1, FieldMemOperand(r7, ConsString::kSecondOffset)); + __ RecordWriteField(r7, + ConsString::kSecondOffset, + r1, + r4, + kLRHasNotBeenSaved, + kDontSaveFPRegs); + __ jmp(&after_writing); + + __ bind(&skip_write_barrier); __ str(r0, FieldMemOperand(r7, ConsString::kFirstOffset)); __ str(r1, FieldMemOperand(r7, ConsString::kSecondOffset)); + + __ bind(&after_writing); + __ mov(r0, Operand(r7)); __ IncrementCounter(counters->string_add_native(), 1, r2, r3); __ add(sp, sp, Operand(2 * kPointerSize)); @@ -6805,6 +6833,9 @@ static const AheadOfTimeWriteBarrierStubList kAheadOfTime[] = { { REG(r5), REG(r0), REG(r6), EMIT_REMEMBERED_SET }, // FastNewClosureStub::Generate { REG(r2), REG(r4), REG(r1), EMIT_REMEMBERED_SET }, + // StringAddStub::Generate + { REG(r7), REG(r1), REG(r4), EMIT_REMEMBERED_SET }, + { REG(r7), REG(r0), REG(r4), EMIT_REMEMBERED_SET }, // Null termination. { REG(no_reg), REG(no_reg), REG(no_reg), EMIT_REMEMBERED_SET} }; diff --git a/src/arm/macro-assembler-arm.cc b/src/arm/macro-assembler-arm.cc index bae5060..e625606 100644 --- a/src/arm/macro-assembler-arm.cc +++ b/src/arm/macro-assembler-arm.cc @@ -1933,8 +1933,34 @@ void MacroAssembler::AllocateAsciiConsString(Register result, Register scratch1, Register scratch2, Label* gc_required) { - Allocate(ConsString::kSize, result, scratch1, scratch2, gc_required, - TAG_OBJECT); + Label allocate_new_space, install_map; + AllocationFlags flags = TAG_OBJECT; + + ExternalReference high_promotion_mode = ExternalReference:: + new_space_high_promotion_mode_active_address(isolate()); + mov(scratch1, Operand(high_promotion_mode)); + ldr(scratch1, MemOperand(r4, 0)); + cmp(scratch1, Operand::Zero()); + b(eq, &allocate_new_space); + + Allocate(ConsString::kSize, + result, + scratch1, + scratch2, + gc_required, + static_cast(flags | PRETENURE_OLD_POINTER_SPACE)); + + jmp(&install_map); + + bind(&allocate_new_space); + Allocate(ConsString::kSize, + result, + scratch1, + scratch2, + gc_required, + flags); + + bind(&install_map); InitializeNewString(result, length, diff --git a/src/assembler.cc b/src/assembler.cc index fff588a..6b0c4b8 100644 --- a/src/assembler.cc +++ b/src/assembler.cc @@ -1203,6 +1203,13 @@ ExternalReference ExternalReference::old_data_space_allocation_limit_address( } +ExternalReference ExternalReference:: + new_space_high_promotion_mode_active_address(Isolate* isolate) { + return ExternalReference( + isolate->heap()->NewSpaceHighPromotionModeActiveAddress()); +} + + ExternalReference ExternalReference::handle_scope_level_address( Isolate* isolate) { return ExternalReference(HandleScope::current_level_address(isolate)); diff --git a/src/assembler.h b/src/assembler.h index 32424cf..6abd5c5 100644 --- a/src/assembler.h +++ b/src/assembler.h @@ -757,6 +757,8 @@ class ExternalReference BASE_EMBEDDED { Isolate* isolate); static ExternalReference old_data_space_allocation_limit_address( Isolate* isolate); + static ExternalReference new_space_high_promotion_mode_active_address( + Isolate* isolate); static ExternalReference double_fp_operation(Token::Value operation, Isolate* isolate); diff --git a/src/heap.cc b/src/heap.cc index 33ba3b8..c58424a 100644 --- a/src/heap.cc +++ b/src/heap.cc @@ -3176,7 +3176,8 @@ void Heap::SetNumberStringCache(Object* number, String* string) { MaybeObject* Heap::NumberToString(Object* number, - bool check_number_string_cache) { + bool check_number_string_cache, + PretenureFlag pretenure) { isolate_->counters()->number_to_string_runtime()->Increment(); if (check_number_string_cache) { Object* cached = GetNumberStringCache(number); @@ -3197,7 +3198,8 @@ MaybeObject* Heap::NumberToString(Object* number, } Object* js_string; - MaybeObject* maybe_js_string = AllocateStringFromOneByte(CStrVector(str)); + MaybeObject* maybe_js_string = + AllocateStringFromOneByte(CStrVector(str), pretenure); if (maybe_js_string->ToObject(&js_string)) { SetNumberStringCache(number, String::cast(js_string)); } diff --git a/src/heap.h b/src/heap.h index b25aa7f..add42c0 100644 --- a/src/heap.h +++ b/src/heap.h @@ -1531,6 +1531,14 @@ class Heap { return new_space_high_promotion_mode_active_; } + inline PretenureFlag GetPretenureMode() { + return new_space_high_promotion_mode_active_ ? TENURED : NOT_TENURED; + } + + inline Address* NewSpaceHighPromotionModeActiveAddress() { + return reinterpret_cast(&new_space_high_promotion_mode_active_); + } + inline intptr_t PromotedTotalSize() { return PromotedSpaceSizeOfObjects() + PromotedExternalMemorySize(); } @@ -1609,7 +1617,8 @@ class Heap { static bool RootCanBeWrittenAfterInitialization(RootListIndex root_index); MUST_USE_RESULT MaybeObject* NumberToString( - Object* number, bool check_number_string_cache = true); + Object* number, bool check_number_string_cache = true, + PretenureFlag pretenure = NOT_TENURED); MUST_USE_RESULT MaybeObject* Uint32ToString( uint32_t value, bool check_number_string_cache = true); @@ -1976,7 +1985,8 @@ class Heap { // Indicates that the new space should be kept small due to high promotion // rates caused by the mutator allocating a lot of long-lived objects. - bool new_space_high_promotion_mode_active_; + // TODO(hpayer): change to bool if no longer accessed from generated code + intptr_t new_space_high_promotion_mode_active_; // Limit that triggers a global GC on the next (normally caused) GC. This // is checked when we have already decided to do a GC to help determine diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc index 73f452a..b168ad5 100644 --- a/src/ia32/code-stubs-ia32.cc +++ b/src/ia32/code-stubs-ia32.cc @@ -5838,8 +5838,33 @@ void StringAddStub::Generate(MacroAssembler* masm) { __ mov(FieldOperand(ecx, ConsString::kLengthOffset), ebx); __ mov(FieldOperand(ecx, ConsString::kHashFieldOffset), Immediate(String::kEmptyHashField)); + + Label skip_write_barrier, after_writing; + ExternalReference high_promotion_mode = ExternalReference:: + new_space_high_promotion_mode_active_address(masm->isolate()); + __ test(Operand::StaticVariable(high_promotion_mode), Immediate(1)); + __ j(zero, &skip_write_barrier); + + __ mov(FieldOperand(ecx, ConsString::kFirstOffset), eax); + __ RecordWriteField(ecx, + ConsString::kFirstOffset, + eax, + ebx, + kDontSaveFPRegs); + __ mov(FieldOperand(ecx, ConsString::kSecondOffset), edx); + __ RecordWriteField(ecx, + ConsString::kSecondOffset, + edx, + ebx, + kDontSaveFPRegs); + __ jmp(&after_writing); + + __ bind(&skip_write_barrier); __ mov(FieldOperand(ecx, ConsString::kFirstOffset), eax); __ mov(FieldOperand(ecx, ConsString::kSecondOffset), edx); + + __ bind(&after_writing); + __ mov(eax, ecx); __ IncrementCounter(counters->string_add_native(), 1); __ ret(2 * kPointerSize); @@ -7371,8 +7396,10 @@ static const AheadOfTimeWriteBarrierStubList kAheadOfTime[] = { { REG(edx), REG(eax), REG(edi), EMIT_REMEMBERED_SET}, // StoreArrayLiteralElementStub::Generate { REG(ebx), REG(eax), REG(ecx), EMIT_REMEMBERED_SET}, - // FastNewClosureStub + // FastNewClosureStub and StringAddStub::Generate { REG(ecx), REG(edx), REG(ebx), EMIT_REMEMBERED_SET}, + // StringAddStub::Generate + { REG(ecx), REG(eax), REG(ebx), EMIT_REMEMBERED_SET}, // Null termination. { REG(no_reg), REG(no_reg), REG(no_reg), EMIT_REMEMBERED_SET} }; diff --git a/src/ia32/macro-assembler-ia32.cc b/src/ia32/macro-assembler-ia32.cc index da29ce7..175b1ca 100644 --- a/src/ia32/macro-assembler-ia32.cc +++ b/src/ia32/macro-assembler-ia32.cc @@ -1603,10 +1603,32 @@ void MacroAssembler::AllocateAsciiConsString(Register result, Register scratch1, Register scratch2, Label* gc_required) { - // Allocate heap number in new space. - Allocate(ConsString::kSize, result, scratch1, scratch2, gc_required, - TAG_OBJECT); + Label allocate_new_space, install_map; + AllocationFlags flags = TAG_OBJECT; + + ExternalReference high_promotion_mode = ExternalReference:: + new_space_high_promotion_mode_active_address(isolate()); + + test(Operand::StaticVariable(high_promotion_mode), Immediate(1)); + j(zero, &allocate_new_space); + + Allocate(ConsString::kSize, + result, + scratch1, + scratch2, + gc_required, + static_cast(flags | PRETENURE_OLD_POINTER_SPACE)); + jmp(&install_map); + + bind(&allocate_new_space); + Allocate(ConsString::kSize, + result, + scratch1, + scratch2, + gc_required, + flags); + bind(&install_map); // Set the map. The other fields are left uninitialized. mov(FieldOperand(result, HeapObject::kMapOffset), Immediate(isolate()->factory()->cons_ascii_string_map())); diff --git a/src/runtime.cc b/src/runtime.cc index 7e7254a..f89a7b6 100644 --- a/src/runtime.cc +++ b/src/runtime.cc @@ -234,7 +234,9 @@ static Handle CreateObjectLiteralBoilerplate( constant_properties, &is_result_from_cache); - Handle boilerplate = isolate->factory()->NewJSObjectFromMap(map); + Handle boilerplate = + isolate->factory()->NewJSObjectFromMap( + map, isolate->heap()->GetPretenureMode()); // Normalize the elements of the boilerplate to save space if needed. if (!should_have_fast_elements) JSObject::NormalizeElements(boilerplate); @@ -338,8 +340,10 @@ Handle Runtime::CreateArrayLiteralBoilerplate( // Create the JSArray. Handle constructor( JSFunction::NativeContextFromLiterals(*literals)->array_function()); - Handle object = - Handle::cast(isolate->factory()->NewJSObject(constructor)); + + Handle object = Handle::cast( + isolate->factory()->NewJSObject( + constructor, isolate->heap()->GetPretenureMode())); ElementsKind constant_elements_kind = static_cast(Smi::cast(elements->get(0))->value()); @@ -6135,7 +6139,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToStringSkipCache) { Object* number = args[0]; RUNTIME_ASSERT(number->IsNumber()); - return isolate->heap()->NumberToString(number, false); + return isolate->heap()->NumberToString( + number, false, isolate->heap()->GetPretenureMode()); } diff --git a/src/serialize.cc b/src/serialize.cc index d4f31c1..3e70edc 100644 --- a/src/serialize.cc +++ b/src/serialize.cc @@ -558,6 +558,11 @@ void ExternalReferenceTable::PopulateTable(Isolate* isolate) { UNCLASSIFIED, 58, "Runtime::AllocateInOldPointerSpace"); + Add(ExternalReference::new_space_high_promotion_mode_active_address(isolate). + address(), + UNCLASSIFIED, + 59, + "Heap::NewSpaceAllocationLimitAddress"); // Add a small set of deopt entry addresses to encoder without generating the // deopt table code, which isn't possible at deserialization time. @@ -568,7 +573,7 @@ void ExternalReferenceTable::PopulateTable(Isolate* isolate) { entry, Deoptimizer::LAZY, Deoptimizer::CALCULATE_ENTRY_ADDRESS); - Add(address, LAZY_DEOPTIMIZATION, 59 + entry, "lazy_deopt"); + Add(address, LAZY_DEOPTIMIZATION, 60 + entry, "lazy_deopt"); } } diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc index ec6665b..ed0a240 100644 --- a/src/x64/code-stubs-x64.cc +++ b/src/x64/code-stubs-x64.cc @@ -4924,8 +4924,34 @@ void StringAddStub::Generate(MacroAssembler* masm) { __ movq(FieldOperand(rcx, ConsString::kLengthOffset), rbx); __ movq(FieldOperand(rcx, ConsString::kHashFieldOffset), Immediate(String::kEmptyHashField)); + + Label skip_write_barrier, after_writing; + ExternalReference high_promotion_mode = ExternalReference:: + new_space_high_promotion_mode_active_address(masm->isolate()); + __ Load(rbx, high_promotion_mode); + __ testb(rbx, Immediate(1)); + __ j(zero, &skip_write_barrier); + + __ movq(FieldOperand(rcx, ConsString::kFirstOffset), rax); + __ RecordWriteField(rcx, + ConsString::kFirstOffset, + rax, + rbx, + kDontSaveFPRegs); + __ movq(FieldOperand(rcx, ConsString::kSecondOffset), rdx); + __ RecordWriteField(rcx, + ConsString::kSecondOffset, + rdx, + rbx, + kDontSaveFPRegs); + __ jmp(&after_writing); + + __ bind(&skip_write_barrier); __ movq(FieldOperand(rcx, ConsString::kFirstOffset), rax); __ movq(FieldOperand(rcx, ConsString::kSecondOffset), rdx); + + __ bind(&after_writing); + __ movq(rax, rcx); __ IncrementCounter(counters->string_add_native(), 1); __ ret(2 * kPointerSize); @@ -6364,8 +6390,11 @@ struct AheadOfTimeWriteBarrierStubList kAheadOfTime[] = { { REG(r11), REG(rax), REG(r15), EMIT_REMEMBERED_SET}, // StoreArrayLiteralElementStub::Generate { REG(rbx), REG(rax), REG(rcx), EMIT_REMEMBERED_SET}, - // FastNewClosureStub::Generate + // FastNewClosureStub::Generate and + // StringAddStub::Generate { REG(rcx), REG(rdx), REG(rbx), EMIT_REMEMBERED_SET}, + // StringAddStub::Generate + { REG(rcx), REG(rax), REG(rbx), EMIT_REMEMBERED_SET}, // Null termination. { REG(no_reg), REG(no_reg), REG(no_reg), EMIT_REMEMBERED_SET} }; diff --git a/src/x64/macro-assembler-x64.cc b/src/x64/macro-assembler-x64.cc index d9db3ad..691894c 100644 --- a/src/x64/macro-assembler-x64.cc +++ b/src/x64/macro-assembler-x64.cc @@ -4066,9 +4066,33 @@ void MacroAssembler::AllocateAsciiConsString(Register result, Register scratch1, Register scratch2, Label* gc_required) { - // Allocate heap number in new space. - Allocate(ConsString::kSize, result, scratch1, scratch2, gc_required, - TAG_OBJECT); + Label allocate_new_space, install_map; + AllocationFlags flags = TAG_OBJECT; + + ExternalReference high_promotion_mode = ExternalReference:: + new_space_high_promotion_mode_active_address(isolate()); + + Load(scratch1, high_promotion_mode); + testb(scratch1, Immediate(1)); + j(zero, &allocate_new_space); + Allocate(ConsString::kSize, + result, + scratch1, + scratch2, + gc_required, + static_cast(flags | PRETENURE_OLD_POINTER_SPACE)); + + jmp(&install_map); + + bind(&allocate_new_space); + Allocate(ConsString::kSize, + result, + scratch1, + scratch2, + gc_required, + flags); + + bind(&install_map); // Set the map. The other fields are left uninitialized. LoadRoot(kScratchRegister, Heap::kConsAsciiStringMapRootIndex); -- 2.7.4