From d3d29c640cf14f0eac2057b4fbffa5fbc0a29231 Mon Sep 17 00:00:00 2001 From: "wingo@igalia.com" Date: Wed, 29 Oct 2014 16:10:59 +0000 Subject: [PATCH] EmitCreateIteratorResult loads map from function's context Caching or serialization can cause full-codegen output to be shared between contexts. CreateIteratorResult, however, was doing the wrong thing by creating results with the map that was current when the code was generated. Instead, we should chase pointers to load the right map from the function's context. R=verwaest@chromium.org BUG=v8:3656 LOG=N Review URL: https://codereview.chromium.org/686063002 Cr-Commit-Position: refs/heads/master@{#24987} git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24987 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/arm/full-codegen-arm.cc | 13 ++++++++----- src/arm64/full-codegen-arm64.cc | 14 +++++++++----- src/ia32/full-codegen-ia32.cc | 13 ++++++++----- src/x64/full-codegen-x64.cc | 13 ++++++++----- 4 files changed, 33 insertions(+), 20 deletions(-) diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc index bdc68b1..1710b60 100644 --- a/src/arm/full-codegen-arm.cc +++ b/src/arm/full-codegen-arm.cc @@ -2330,23 +2330,26 @@ void FullCodeGenerator::EmitCreateIteratorResult(bool done) { Label gc_required; Label allocated; - Handle map(isolate()->native_context()->iterator_result_map()); + const int instance_size = 5 * kPointerSize; + DCHECK_EQ(isolate()->native_context()->iterator_result_map()->instance_size(), + instance_size); - __ Allocate(map->instance_size(), r0, r2, r3, &gc_required, TAG_OBJECT); + __ Allocate(instance_size, r0, r2, r3, &gc_required, TAG_OBJECT); __ jmp(&allocated); __ bind(&gc_required); - __ Push(Smi::FromInt(map->instance_size())); + __ Push(Smi::FromInt(instance_size)); __ CallRuntime(Runtime::kAllocateInNewSpace, 1); __ ldr(context_register(), MemOperand(fp, StandardFrameConstants::kContextOffset)); __ bind(&allocated); - __ mov(r1, Operand(map)); + __ ldr(r1, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX)); + __ ldr(r1, FieldMemOperand(r1, GlobalObject::kNativeContextOffset)); + __ ldr(r1, ContextOperand(r1, Context::ITERATOR_RESULT_MAP_INDEX)); __ pop(r2); __ mov(r3, Operand(isolate()->factory()->ToBoolean(done))); __ mov(r4, Operand(isolate()->factory()->empty_fixed_array())); - DCHECK_EQ(map->instance_size(), 5 * kPointerSize); __ str(r1, FieldMemOperand(r0, HeapObject::kMapOffset)); __ str(r4, FieldMemOperand(r0, JSObject::kPropertiesOffset)); __ str(r4, FieldMemOperand(r0, JSObject::kElementsOffset)); diff --git a/src/arm64/full-codegen-arm64.cc b/src/arm64/full-codegen-arm64.cc index 792dc30..4262875 100644 --- a/src/arm64/full-codegen-arm64.cc +++ b/src/arm64/full-codegen-arm64.cc @@ -5031,16 +5031,18 @@ void FullCodeGenerator::EmitCreateIteratorResult(bool done) { Label gc_required; Label allocated; - Handle map(isolate()->native_context()->iterator_result_map()); + const int instance_size = 5 * kPointerSize; + DCHECK_EQ(isolate()->native_context()->iterator_result_map()->instance_size(), + instance_size); // Allocate and populate an object with this form: { value: VAL, done: DONE } Register result = x0; - __ Allocate(map->instance_size(), result, x10, x11, &gc_required, TAG_OBJECT); + __ Allocate(instance_size, result, x10, x11, &gc_required, TAG_OBJECT); __ B(&allocated); __ Bind(&gc_required); - __ Push(Smi::FromInt(map->instance_size())); + __ Push(Smi::FromInt(instance_size)); __ CallRuntime(Runtime::kAllocateInNewSpace, 1); __ Ldr(context_register(), MemOperand(fp, StandardFrameConstants::kContextOffset)); @@ -5051,11 +5053,13 @@ void FullCodeGenerator::EmitCreateIteratorResult(bool done) { Register boolean_done = x3; Register empty_fixed_array = x4; Register untagged_result = x5; - __ Mov(map_reg, Operand(map)); + __ Ldr(map_reg, GlobalObjectMemOperand()); + __ Ldr(map_reg, FieldMemOperand(map_reg, GlobalObject::kNativeContextOffset)); + __ Ldr(map_reg, + ContextMemOperand(map_reg, Context::ITERATOR_RESULT_MAP_INDEX)); __ Pop(result_value); __ Mov(boolean_done, Operand(isolate()->factory()->ToBoolean(done))); __ Mov(empty_fixed_array, Operand(isolate()->factory()->empty_fixed_array())); - DCHECK_EQ(map->instance_size(), 5 * kPointerSize); STATIC_ASSERT(JSObject::kPropertiesOffset + kPointerSize == JSObject::kElementsOffset); STATIC_ASSERT(JSGeneratorObject::kResultValuePropertyOffset + kPointerSize == diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc index 920d036..acf59b4 100644 --- a/src/ia32/full-codegen-ia32.cc +++ b/src/ia32/full-codegen-ia32.cc @@ -2245,22 +2245,25 @@ void FullCodeGenerator::EmitCreateIteratorResult(bool done) { Label gc_required; Label allocated; - Handle map(isolate()->native_context()->iterator_result_map()); + const int instance_size = 5 * kPointerSize; + DCHECK_EQ(isolate()->native_context()->iterator_result_map()->instance_size(), + instance_size); - __ Allocate(map->instance_size(), eax, ecx, edx, &gc_required, TAG_OBJECT); + __ Allocate(instance_size, eax, ecx, edx, &gc_required, TAG_OBJECT); __ jmp(&allocated); __ bind(&gc_required); - __ Push(Smi::FromInt(map->instance_size())); + __ Push(Smi::FromInt(instance_size)); __ CallRuntime(Runtime::kAllocateInNewSpace, 1); __ mov(context_register(), Operand(ebp, StandardFrameConstants::kContextOffset)); __ bind(&allocated); - __ mov(ebx, map); + __ mov(ebx, Operand(esi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); + __ mov(ebx, FieldOperand(ebx, GlobalObject::kNativeContextOffset)); + __ mov(ebx, ContextOperand(ebx, Context::ITERATOR_RESULT_MAP_INDEX)); __ pop(ecx); __ mov(edx, isolate()->factory()->ToBoolean(done)); - DCHECK_EQ(map->instance_size(), 5 * kPointerSize); __ mov(FieldOperand(eax, HeapObject::kMapOffset), ebx); __ mov(FieldOperand(eax, JSObject::kPropertiesOffset), isolate()->factory()->empty_fixed_array()); diff --git a/src/x64/full-codegen-x64.cc b/src/x64/full-codegen-x64.cc index 085a55d..25bfd34 100644 --- a/src/x64/full-codegen-x64.cc +++ b/src/x64/full-codegen-x64.cc @@ -2277,22 +2277,25 @@ void FullCodeGenerator::EmitCreateIteratorResult(bool done) { Label gc_required; Label allocated; - Handle map(isolate()->native_context()->iterator_result_map()); + const int instance_size = 5 * kPointerSize; + DCHECK_EQ(isolate()->native_context()->iterator_result_map()->instance_size(), + instance_size); - __ Allocate(map->instance_size(), rax, rcx, rdx, &gc_required, TAG_OBJECT); + __ Allocate(instance_size, rax, rcx, rdx, &gc_required, TAG_OBJECT); __ jmp(&allocated); __ bind(&gc_required); - __ Push(Smi::FromInt(map->instance_size())); + __ Push(Smi::FromInt(instance_size)); __ CallRuntime(Runtime::kAllocateInNewSpace, 1); __ movp(context_register(), Operand(rbp, StandardFrameConstants::kContextOffset)); __ bind(&allocated); - __ Move(rbx, map); + __ movp(rbx, Operand(rsi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); + __ movp(rbx, FieldOperand(rbx, GlobalObject::kNativeContextOffset)); + __ movp(rbx, ContextOperand(rbx, Context::ITERATOR_RESULT_MAP_INDEX)); __ Pop(rcx); __ Move(rdx, isolate()->factory()->ToBoolean(done)); - DCHECK_EQ(map->instance_size(), 5 * kPointerSize); __ movp(FieldOperand(rax, HeapObject::kMapOffset), rbx); __ Move(FieldOperand(rax, JSObject::kPropertiesOffset), isolate()->factory()->empty_fixed_array()); -- 2.7.4