From bbcafaa2d5d6274d2179537855495537abe4d15e Mon Sep 17 00:00:00 2001 From: "erik.corry@gmail.com" Date: Wed, 28 Sep 2011 10:32:12 +0000 Subject: [PATCH] Make sure we don't flush the pregenerated stubs, since they need to be always present, so that we can call them from other stubs without trying to generate stubs while we are generating stubs. Review URL: http://codereview.chromium.org/8052029 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@9459 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/arm/code-stubs-arm.cc | 12 ++++++------ src/ia32/code-stubs-ia32.cc | 9 +++++---- src/isolate.cc | 2 +- src/objects-inl.h | 13 +++++++++++++ src/objects.h | 6 ++++++ src/stub-cache.cc | 27 ++++++++++++++++++++------- src/x64/code-stubs-x64.cc | 8 ++++---- 7 files changed, 55 insertions(+), 22 deletions(-) diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc index d693ea1..f33327c 100644 --- a/src/arm/code-stubs-arm.cc +++ b/src/arm/code-stubs-arm.cc @@ -877,8 +877,8 @@ bool WriteInt32ToHeapNumberStub::IsPregenerated() { void WriteInt32ToHeapNumberStub::GenerateFixedRegStubsAheadOfTime() { WriteInt32ToHeapNumberStub stub1(r1, r0, r2); WriteInt32ToHeapNumberStub stub2(r2, r0, r3); - Handle code1 = stub1.GetCode(); - Handle code2 = stub2.GetCode(); + Handle code1 = stub1.GetCode()->set_is_pregenerated(true); + Handle code2 = stub2.GetCode()->set_is_pregenerated(true); } @@ -3413,7 +3413,7 @@ void CodeStub::GenerateStubsAheadOfTime() { void CodeStub::GenerateFPStubs() { CEntryStub save_doubles(1, kSaveFPRegs); - Handle code = save_doubles.GetCode(); + Handle code = save_doubles.GetCode()->set_is_pregenerated(true); code->GetIsolate()->set_fp_stubs_generated(true); } @@ -6877,9 +6877,9 @@ bool RecordWriteStub::IsPregenerated() { void StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime() { StoreBufferOverflowStub stub1(kDontSaveFPRegs); - stub1.GetCode(); + stub1.GetCode()->set_is_pregenerated(true); StoreBufferOverflowStub stub2(kSaveFPRegs); - stub2.GetCode(); + stub2.GetCode()->set_is_pregenerated(true); } @@ -6892,7 +6892,7 @@ void RecordWriteStub::GenerateFixedRegStubsAheadOfTime() { entry->address, entry->action, kDontSaveFPRegs); - stub.GetCode(); + stub.GetCode()->set_is_pregenerated(true); } } diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc index 0707234..197c8c9 100644 --- a/src/ia32/code-stubs-ia32.cc +++ b/src/ia32/code-stubs-ia32.cc @@ -4424,6 +4424,7 @@ void CodeStub::GenerateStubsAheadOfTime() { void CodeStub::GenerateFPStubs() { CEntryStub save_doubles(1, kSaveFPRegs); Handle code = save_doubles.GetCode(); + code->set_is_pregenerated(true); code->GetIsolate()->set_fp_stubs_generated(true); } @@ -6667,7 +6668,7 @@ struct AheadOfTimeWriteBarrierStubList kAheadOfTime[] = { { ebx, eax, edi, EMIT_REMEMBERED_SET }, // Used in CompileArrayPushCall. { ebx, ecx, edx, EMIT_REMEMBERED_SET }, - // Used in CompileStoreGlobal. + // Used in CompileStoreGlobal and CallFunctionStub. { ebx, ecx, edx, OMIT_REMEMBERED_SET }, // Used in StoreStubCompiler::CompileStoreField and // KeyedStoreStubCompiler::CompileStoreField via GenerateStoreField. @@ -6704,12 +6705,12 @@ bool RecordWriteStub::IsPregenerated() { void StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime() { StoreBufferOverflowStub stub1(kDontSaveFPRegs); - stub1.GetCode(); + stub1.GetCode()->set_is_pregenerated(true); CpuFeatures::TryForceFeatureScope scope(SSE2); if (CpuFeatures::IsSupported(SSE2)) { StoreBufferOverflowStub stub2(kSaveFPRegs); - stub2.GetCode(); + stub2.GetCode()->set_is_pregenerated(true); } } @@ -6723,7 +6724,7 @@ void RecordWriteStub::GenerateFixedRegStubsAheadOfTime() { entry->address, entry->action, kDontSaveFPRegs); - stub.GetCode(); + stub.GetCode()->set_is_pregenerated(true); } } diff --git a/src/isolate.cc b/src/isolate.cc index 311ab49..951f428 100644 --- a/src/isolate.cc +++ b/src/isolate.cc @@ -1768,7 +1768,7 @@ bool Isolate::Init(Deserializer* des) { // If we are deserializing, read the state into the now-empty heap. if (des != NULL) { des->Deserialize(); - stub_cache_->Clear(); + stub_cache_->Initialize(true); } // Deserializing may put strange things in the root array's copy of the diff --git a/src/objects-inl.h b/src/objects-inl.h index 07223e5..a8179cf 100644 --- a/src/objects-inl.h +++ b/src/objects-inl.h @@ -2935,6 +2935,19 @@ void Code::set_major_key(int major) { } +bool Code::is_pregenerated() { + return kind() == STUB && IsPregeneratedField::decode(flags()); +} + + +void Code::set_is_pregenerated(bool value) { + ASSERT(kind() == STUB); + Flags f = flags(); + f = static_cast(IsPregeneratedField::update(f, value)); + set_flags(f); +} + + bool Code::optimizable() { ASSERT(kind() == FUNCTION); return READ_BYTE_FIELD(this, kOptimizableOffset) == 1; diff --git a/src/objects.h b/src/objects.h index 8a83d00..29564d4 100644 --- a/src/objects.h +++ b/src/objects.h @@ -3657,6 +3657,11 @@ class Code: public HeapObject { inline int major_key(); inline void set_major_key(int value); + // For stubs, tells whether they should always exist, so that they can be + // called from other stubs. + inline bool is_pregenerated(); + inline void set_is_pregenerated(bool value); + // [optimizable]: For FUNCTION kind, tells if it is optimizable. inline bool optimizable(); inline void set_optimizable(bool value); @@ -3880,6 +3885,7 @@ class Code: public HeapObject { class KindField: public BitField {}; class CacheHolderField: public BitField {}; class ExtraICStateField: public BitField {}; + class IsPregeneratedField: public BitField {}; // Signed field cannot be encoded using the BitField class. static const int kArgumentsCountShift = 14; diff --git a/src/stub-cache.cc b/src/stub-cache.cc index 5596330..c06a11d 100644 --- a/src/stub-cache.cc +++ b/src/stub-cache.cc @@ -55,7 +55,15 @@ void StubCache::Initialize(bool create_heap_objects) { ASSERT(IsPowerOf2(kSecondaryTableSize)); if (create_heap_objects) { HandleScope scope; - Clear(); + Code* empty = isolate_->builtins()->builtin(Builtins::kIllegal); + for (int i = 0; i < kPrimaryTableSize; i++) { + primary_[i].key = heap()->empty_string(); + primary_[i].value = empty; + } + for (int j = 0; j < kSecondaryTableSize; j++) { + secondary_[j].key = heap()->empty_string(); + secondary_[j].value = empty; + } } } @@ -1099,15 +1107,20 @@ MaybeObject* StubCache::ComputeCallDebugPrepareStepIn( void StubCache::Clear() { + Code* empty = isolate_->builtins()->builtin(Builtins::kIllegal); for (int i = 0; i < kPrimaryTableSize; i++) { - primary_[i].key = heap()->empty_string(); - primary_[i].value = isolate_->builtins()->builtin( - Builtins::kIllegal); + Code* code = primary_[i].value; + if (code != empty && !code->is_pregenerated()) { + primary_[i].key = heap()->empty_string(); + primary_[i].value = empty; + } } for (int j = 0; j < kSecondaryTableSize; j++) { - secondary_[j].key = heap()->empty_string(); - secondary_[j].value = isolate_->builtins()->builtin( - Builtins::kIllegal); + Code* code = secondary_[j].value; + if (code != empty && !code->is_pregenerated()) { + secondary_[j].key = heap()->empty_string(); + secondary_[j].value = empty; + } } } diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc index 034c5a0..059a79e 100644 --- a/src/x64/code-stubs-x64.cc +++ b/src/x64/code-stubs-x64.cc @@ -3376,7 +3376,7 @@ bool CEntryStub::IsPregenerated() { void CodeStub::GenerateStubsAheadOfTime() { CEntryStub save_doubles(1, kSaveFPRegs); - save_doubles.GetCode(); + save_doubles.GetCode()->set_is_pregenerated(true); StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime(); // It is important that the store buffer overflow stubs are generated first. RecordWriteStub::GenerateFixedRegStubsAheadOfTime(); @@ -5616,9 +5616,9 @@ bool RecordWriteStub::IsPregenerated() { void StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime() { StoreBufferOverflowStub stub1(kDontSaveFPRegs); - stub1.GetCode(); + stub1.GetCode()->set_is_pregenerated(true); StoreBufferOverflowStub stub2(kSaveFPRegs); - stub2.GetCode(); + stub2.GetCode()->set_is_pregenerated(true); } @@ -5631,7 +5631,7 @@ void RecordWriteStub::GenerateFixedRegStubsAheadOfTime() { entry->address, entry->action, kDontSaveFPRegs); - stub.GetCode(); + stub.GetCode()->set_is_pregenerated(true); } } -- 2.7.4