From: bmeurer@chromium.org Date: Mon, 26 May 2014 08:13:09 +0000 (+0000) Subject: Skip write barriers in the fast case when setting up local context. X-Git-Tag: upstream/4.7.83~8985 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=683bc694ad48849aa43156e1f3c5fcbb7266fd9d;p=platform%2Fupstream%2Fv8.git Skip write barriers in the fast case when setting up local context. The FastNewContextStub always allocates in new space, so we don't need to update the write barrier when copying the parameters to the newly allocated context. R=hpayer@chromium.org Review URL: https://codereview.chromium.org/297203002 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@21481 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc index cb7d7da..ccde8b6 100644 --- a/src/arm/full-codegen-arm.cc +++ b/src/arm/full-codegen-arm.cc @@ -212,6 +212,7 @@ void FullCodeGenerator::Generate() { if (heap_slots > 0) { // Argument to NewContext is the function, which is still in r1. Comment cmnt(masm_, "[ Allocate context"); + bool need_write_barrier = true; if (FLAG_harmony_scoping && info->scope()->is_global_scope()) { __ push(r1); __ Push(info->scope()->GetScopeInfo()); @@ -219,6 +220,8 @@ void FullCodeGenerator::Generate() { } else if (heap_slots <= FastNewContextStub::kMaximumSlots) { FastNewContextStub stub(isolate(), heap_slots); __ CallStub(&stub); + // Result of FastNewContextStub is always in new space. + need_write_barrier = false; } else { __ push(r1); __ CallRuntime(Runtime::kHiddenNewFunctionContext, 1); @@ -242,8 +245,15 @@ void FullCodeGenerator::Generate() { __ str(r0, target); // Update the write barrier. - __ RecordWriteContextSlot( - cp, target.offset(), r0, r3, kLRHasBeenSaved, kDontSaveFPRegs); + if (need_write_barrier) { + __ RecordWriteContextSlot( + cp, target.offset(), r0, r3, kLRHasBeenSaved, kDontSaveFPRegs); + } else if (FLAG_debug_code) { + Label done; + __ JumpIfInNewSpace(cp, r0, &done); + __ Abort(kExpectedNewSpaceObject); + __ bind(&done); + } } } } diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc index d2e665e..b417c80 100644 --- a/src/arm/lithium-codegen-arm.cc +++ b/src/arm/lithium-codegen-arm.cc @@ -179,10 +179,13 @@ bool LCodeGen::GeneratePrologue() { int heap_slots = info()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; if (heap_slots > 0) { Comment(";;; Allocate local context"); + bool need_write_barrier = true; // Argument to NewContext is the function, which is in r1. if (heap_slots <= FastNewContextStub::kMaximumSlots) { FastNewContextStub stub(isolate(), heap_slots); __ CallStub(&stub); + // Result of FastNewContextStub is always in new space. + need_write_barrier = false; } else { __ push(r1); __ CallRuntime(Runtime::kHiddenNewFunctionContext, 1); @@ -205,13 +208,20 @@ bool LCodeGen::GeneratePrologue() { MemOperand target = ContextOperand(cp, var->index()); __ str(r0, target); // Update the write barrier. This clobbers r3 and r0. - __ RecordWriteContextSlot( - cp, - target.offset(), - r0, - r3, - GetLinkRegisterState(), - kSaveFPRegs); + if (need_write_barrier) { + __ RecordWriteContextSlot( + cp, + target.offset(), + r0, + r3, + GetLinkRegisterState(), + kSaveFPRegs); + } else if (FLAG_debug_code) { + Label done; + __ JumpIfInNewSpace(cp, r0, &done); + __ Abort(kExpectedNewSpaceObject); + __ bind(&done); + } } } Comment(";;; End allocate local context"); diff --git a/src/arm64/full-codegen-arm64.cc b/src/arm64/full-codegen-arm64.cc index 87b9aa4..1dcdf3c 100644 --- a/src/arm64/full-codegen-arm64.cc +++ b/src/arm64/full-codegen-arm64.cc @@ -211,6 +211,7 @@ void FullCodeGenerator::Generate() { if (heap_slots > 0) { // Argument to NewContext is the function, which is still in x1. Comment cmnt(masm_, "[ Allocate context"); + bool need_write_barrier = true; if (FLAG_harmony_scoping && info->scope()->is_global_scope()) { __ Mov(x10, Operand(info->scope()->GetScopeInfo())); __ Push(x1, x10); @@ -218,6 +219,8 @@ void FullCodeGenerator::Generate() { } else if (heap_slots <= FastNewContextStub::kMaximumSlots) { FastNewContextStub stub(isolate(), heap_slots); __ CallStub(&stub); + // Result of FastNewContextStub is always in new space. + need_write_barrier = false; } else { __ Push(x1); __ CallRuntime(Runtime::kHiddenNewFunctionContext, 1); @@ -241,8 +244,15 @@ void FullCodeGenerator::Generate() { __ Str(x10, target); // Update the write barrier. - __ RecordWriteContextSlot( - cp, target.offset(), x10, x11, kLRHasBeenSaved, kDontSaveFPRegs); + if (need_write_barrier) { + __ RecordWriteContextSlot( + cp, target.offset(), x10, x11, kLRHasBeenSaved, kDontSaveFPRegs); + } else if (FLAG_debug_code) { + Label done; + __ JumpIfInNewSpace(cp, &done); + __ Abort(kExpectedNewSpaceObject); + __ bind(&done); + } } } } diff --git a/src/arm64/lithium-codegen-arm64.cc b/src/arm64/lithium-codegen-arm64.cc index 9161aaf..3660551 100644 --- a/src/arm64/lithium-codegen-arm64.cc +++ b/src/arm64/lithium-codegen-arm64.cc @@ -694,10 +694,13 @@ bool LCodeGen::GeneratePrologue() { int heap_slots = info()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; if (heap_slots > 0) { Comment(";;; Allocate local context"); + bool need_write_barrier = true; // Argument to NewContext is the function, which is in x1. if (heap_slots <= FastNewContextStub::kMaximumSlots) { FastNewContextStub stub(isolate(), heap_slots); __ CallStub(&stub); + // Result of FastNewContextStub is always in new space. + need_write_barrier = false; } else { __ Push(x1); __ CallRuntime(Runtime::kHiddenNewFunctionContext, 1); @@ -723,8 +726,15 @@ bool LCodeGen::GeneratePrologue() { MemOperand target = ContextMemOperand(cp, var->index()); __ Str(value, target); // Update the write barrier. This clobbers value and scratch. - __ RecordWriteContextSlot(cp, target.offset(), value, scratch, - GetLinkRegisterState(), kSaveFPRegs); + if (need_write_barrier) { + __ RecordWriteContextSlot(cp, target.offset(), value, scratch, + GetLinkRegisterState(), kSaveFPRegs); + } else if (FLAG_debug_code) { + Label done; + __ JumpIfInNewSpace(cp, &done); + __ Abort(kExpectedNewSpaceObject); + __ bind(&done); + } } } Comment(";;; End allocate local context"); diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc index 07afba6..88dad86 100644 --- a/src/ia32/full-codegen-ia32.cc +++ b/src/ia32/full-codegen-ia32.cc @@ -198,6 +198,7 @@ void FullCodeGenerator::Generate() { int heap_slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; if (heap_slots > 0) { Comment cmnt(masm_, "[ Allocate context"); + bool need_write_barrier = true; // Argument to NewContext is the function, which is still in edi. if (FLAG_harmony_scoping && info->scope()->is_global_scope()) { __ push(edi); @@ -206,6 +207,8 @@ void FullCodeGenerator::Generate() { } else if (heap_slots <= FastNewContextStub::kMaximumSlots) { FastNewContextStub stub(isolate(), heap_slots); __ CallStub(&stub); + // Result of FastNewContextStub is always in new space. + need_write_barrier = false; } else { __ push(edi); __ CallRuntime(Runtime::kHiddenNewFunctionContext, 1); @@ -229,11 +232,18 @@ void FullCodeGenerator::Generate() { int context_offset = Context::SlotOffset(var->index()); __ mov(Operand(esi, context_offset), eax); // Update the write barrier. This clobbers eax and ebx. - __ RecordWriteContextSlot(esi, - context_offset, - eax, - ebx, - kDontSaveFPRegs); + if (need_write_barrier) { + __ RecordWriteContextSlot(esi, + context_offset, + eax, + ebx, + kDontSaveFPRegs); + } else if (FLAG_debug_code) { + Label done; + __ JumpIfInNewSpace(esi, eax, &done, Label::kNear); + __ Abort(kExpectedNewSpaceObject); + __ bind(&done); + } } } } diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc index 114cf74..c85f1ca 100644 --- a/src/ia32/lithium-codegen-ia32.cc +++ b/src/ia32/lithium-codegen-ia32.cc @@ -254,10 +254,13 @@ bool LCodeGen::GeneratePrologue() { int heap_slots = info_->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; if (heap_slots > 0) { Comment(";;; Allocate local context"); + bool need_write_barrier = true; // Argument to NewContext is the function, which is still in edi. if (heap_slots <= FastNewContextStub::kMaximumSlots) { FastNewContextStub stub(isolate(), heap_slots); __ CallStub(&stub); + // Result of FastNewContextStub is always in new space. + need_write_barrier = false; } else { __ push(edi); __ CallRuntime(Runtime::kHiddenNewFunctionContext, 1); @@ -281,11 +284,18 @@ bool LCodeGen::GeneratePrologue() { int context_offset = Context::SlotOffset(var->index()); __ mov(Operand(esi, context_offset), eax); // Update the write barrier. This clobbers eax and ebx. - __ RecordWriteContextSlot(esi, - context_offset, - eax, - ebx, - kDontSaveFPRegs); + if (need_write_barrier) { + __ RecordWriteContextSlot(esi, + context_offset, + eax, + ebx, + kDontSaveFPRegs); + } else if (FLAG_debug_code) { + Label done; + __ JumpIfInNewSpace(esi, eax, &done, Label::kNear); + __ Abort(kExpectedNewSpaceObject); + __ bind(&done); + } } } Comment(";;; End allocate local context"); diff --git a/src/objects.h b/src/objects.h index 7a3e07a..8ef7f20 100644 --- a/src/objects.h +++ b/src/objects.h @@ -1071,6 +1071,7 @@ template inline bool Is(Object* obj); "Expected fixed array in register r2") \ V(kExpectedFixedArrayInRegisterRbx, \ "Expected fixed array in register rbx") \ + V(kExpectedNewSpaceObject, "Expected new space object") \ V(kExpectedSmiOrHeapNumber, "Expected smi or HeapNumber") \ V(kExpectedUndefinedOrCell, \ "Expected undefined or cell in register") \ diff --git a/src/x64/full-codegen-x64.cc b/src/x64/full-codegen-x64.cc index 76225da..97c9c5c 100644 --- a/src/x64/full-codegen-x64.cc +++ b/src/x64/full-codegen-x64.cc @@ -199,6 +199,7 @@ void FullCodeGenerator::Generate() { int heap_slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; if (heap_slots > 0) { Comment cmnt(masm_, "[ Allocate context"); + bool need_write_barrier = true; // Argument to NewContext is the function, which is still in rdi. if (FLAG_harmony_scoping && info->scope()->is_global_scope()) { __ Push(rdi); @@ -207,6 +208,8 @@ void FullCodeGenerator::Generate() { } else if (heap_slots <= FastNewContextStub::kMaximumSlots) { FastNewContextStub stub(isolate(), heap_slots); __ CallStub(&stub); + // Result of FastNewContextStub is always in new space. + need_write_barrier = false; } else { __ Push(rdi); __ CallRuntime(Runtime::kHiddenNewFunctionContext, 1); @@ -230,8 +233,15 @@ void FullCodeGenerator::Generate() { int context_offset = Context::SlotOffset(var->index()); __ movp(Operand(rsi, context_offset), rax); // Update the write barrier. This clobbers rax and rbx. - __ RecordWriteContextSlot( - rsi, context_offset, rax, rbx, kDontSaveFPRegs); + if (need_write_barrier) { + __ RecordWriteContextSlot( + rsi, context_offset, rax, rbx, kDontSaveFPRegs); + } else if (FLAG_debug_code) { + Label done; + __ JumpIfInNewSpace(rsi, rax, &done, Label::kNear); + __ Abort(kExpectedNewSpaceObject); + __ bind(&done); + } } } } diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc index 5be849f..1230cb3 100644 --- a/src/x64/lithium-codegen-x64.cc +++ b/src/x64/lithium-codegen-x64.cc @@ -191,10 +191,13 @@ bool LCodeGen::GeneratePrologue() { int heap_slots = info_->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; if (heap_slots > 0) { Comment(";;; Allocate local context"); + bool need_write_barrier = true; // Argument to NewContext is the function, which is still in rdi. if (heap_slots <= FastNewContextStub::kMaximumSlots) { FastNewContextStub stub(isolate(), heap_slots); __ CallStub(&stub); + // Result of FastNewContextStub is always in new space. + need_write_barrier = false; } else { __ Push(rdi); __ CallRuntime(Runtime::kHiddenNewFunctionContext, 1); @@ -218,7 +221,14 @@ bool LCodeGen::GeneratePrologue() { int context_offset = Context::SlotOffset(var->index()); __ movp(Operand(rsi, context_offset), rax); // Update the write barrier. This clobbers rax and rbx. - __ RecordWriteContextSlot(rsi, context_offset, rax, rbx, kSaveFPRegs); + if (need_write_barrier) { + __ RecordWriteContextSlot(rsi, context_offset, rax, rbx, kSaveFPRegs); + } else if (FLAG_debug_code) { + Label done; + __ JumpIfInNewSpace(rsi, rax, &done, Label::kNear); + __ Abort(kExpectedNewSpaceObject); + __ bind(&done); + } } } Comment(";;; End allocate local context");