void WriteInt32ToHeapNumberStub::GenerateFixedRegStubsAheadOfTime() {
WriteInt32ToHeapNumberStub stub1(r1, r0, r2);
WriteInt32ToHeapNumberStub stub2(r2, r0, r3);
- Handle<Code> code1 = stub1.GetCode();
- Handle<Code> code2 = stub2.GetCode();
+ Handle<Code> code1 = stub1.GetCode()->set_is_pregenerated(true);
+ Handle<Code> code2 = stub2.GetCode()->set_is_pregenerated(true);
}
void CodeStub::GenerateFPStubs() {
CEntryStub save_doubles(1, kSaveFPRegs);
- Handle<Code> code = save_doubles.GetCode();
+ Handle<Code> code = save_doubles.GetCode()->set_is_pregenerated(true);
code->GetIsolate()->set_fp_stubs_generated(true);
}
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);
}
entry->address,
entry->action,
kDontSaveFPRegs);
- stub.GetCode();
+ stub.GetCode()->set_is_pregenerated(true);
}
}
void CodeStub::GenerateFPStubs() {
CEntryStub save_doubles(1, kSaveFPRegs);
Handle<Code> code = save_doubles.GetCode();
+ code->set_is_pregenerated(true);
code->GetIsolate()->set_fp_stubs_generated(true);
}
{ 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.
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);
}
}
entry->address,
entry->action,
kDontSaveFPRegs);
- stub.GetCode();
+ stub.GetCode()->set_is_pregenerated(true);
}
}
// 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
}
+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<Flags>(IsPregeneratedField::update(f, value));
+ set_flags(f);
+}
+
+
bool Code::optimizable() {
ASSERT(kind() == FUNCTION);
return READ_BYTE_FIELD(this, kOptimizableOffset) == 1;
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);
class KindField: public BitField<Kind, 7, 4> {};
class CacheHolderField: public BitField<InlineCacheHolderFlag, 11, 1> {};
class ExtraICStateField: public BitField<ExtraICState, 12, 2> {};
+ class IsPregeneratedField: public BitField<bool, 14, 1> {};
// Signed field cannot be encoded using the BitField class.
static const int kArgumentsCountShift = 14;
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;
+ }
}
}
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;
+ }
}
}
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();
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);
}
entry->address,
entry->action,
kDontSaveFPRegs);
- stub.GetCode();
+ stub.GetCode()->set_is_pregenerated(true);
}
}