Index: src/code-stubs.cc |
=================================================================== |
--- src/code-stubs.cc (revision 3434) |
+++ src/code-stubs.cc (working copy) |
@@ -35,85 +35,120 @@ |
namespace v8 { |
namespace internal { |
-Handle<Code> CodeStub::GetCode() { |
- bool custom_cache = has_custom_cache(); |
+bool CodeStub::FindCodeInCache(Code** code_out) { |
+ if (has_custom_cache()) return GetCustomCache(code_out); |
+ int index = Heap::code_stubs()->FindEntry(GetKey()); |
+ if (index != NumberDictionary::kNotFound) { |
+ *code_out = Code::cast(Heap::code_stubs()->ValueAt(index)); |
+ return true; |
+ } |
+ return false; |
+} |
- int index = 0; |
- uint32_t key = 0; |
- if (custom_cache) { |
- Code* cached; |
- if (GetCustomCache(&cached)) { |
- return Handle<Code>(cached); |
- } else { |
- index = NumberDictionary::kNotFound; |
- } |
- } else { |
- key = GetKey(); |
- index = Heap::code_stubs()->FindEntry(key); |
- if (index != NumberDictionary::kNotFound) |
- return Handle<Code>(Code::cast(Heap::code_stubs()->ValueAt(index))); |
+ |
+void CodeStub::GenerateCode(MacroAssembler* masm) { |
+ // Update the static counter each time a new code stub is generated. |
+ Counters::code_stubs.Increment(); |
+ // Nested stubs are not allowed for leafs. |
+ masm->set_allow_stub_calls(AllowsStubCalls()); |
+ // Generate the code for the stub. |
+ masm->set_generating_stub(true); |
+ Generate(masm); |
+} |
+ |
+ |
+void CodeStub::RecordCodeGeneration(Code* code, MacroAssembler* masm) { |
+ code->set_major_key(MajorKey()); |
+ |
+ // Add unresolved entries in the code to the fixup list. |
+ Bootstrapper::AddFixup(code, masm); |
+ |
+ LOG(CodeCreateEvent(Logger::STUB_TAG, code, GetName())); |
+ Counters::total_stubs_code_size.Increment(code->instruction_size()); |
+ |
+#ifdef ENABLE_DISASSEMBLER |
+ if (FLAG_print_code_stubs) { |
+#ifdef DEBUG |
+ Print(); |
+#endif |
+ code->Disassemble(GetName()); |
+ PrintF("\n"); |
} |
+#endif |
+} |
- Code* result; |
- { |
+ |
+Handle<Code> CodeStub::GetCode() { |
+ Code* code; |
+ if (!FindCodeInCache(&code)) { |
v8::HandleScope scope; |
- // Update the static counter each time a new code stub is generated. |
- Counters::code_stubs.Increment(); |
- |
// Generate the new code. |
MacroAssembler masm(NULL, 256); |
+ GenerateCode(&masm); |
- // Nested stubs are not allowed for leafs. |
- masm.set_allow_stub_calls(AllowsStubCalls()); |
- |
- // Generate the code for the stub. |
- masm.set_generating_stub(true); |
- Generate(&masm); |
- |
// Create the code object. |
CodeDesc desc; |
masm.GetCode(&desc); |
- // Copy the generated code into a heap object, and store the major key. |
+ // Copy the generated code into a heap object. |
Code::Flags flags = Code::ComputeFlags(Code::STUB, InLoop()); |
- Handle<Code> code = Factory::NewCode(desc, NULL, flags, masm.CodeObject()); |
- code->set_major_key(MajorKey()); |
+ Handle<Code> new_object = |
+ Factory::NewCode(desc, NULL, flags, masm.CodeObject()); |
+ RecordCodeGeneration(*new_object, &masm); |
- // Add unresolved entries in the code to the fixup list. |
- Bootstrapper::AddFixup(*code, &masm); |
- |
- LOG(CodeCreateEvent(Logger::STUB_TAG, *code, GetName())); |
- Counters::total_stubs_code_size.Increment(code->instruction_size()); |
- |
-#ifdef ENABLE_DISASSEMBLER |
- if (FLAG_print_code_stubs) { |
-#ifdef DEBUG |
- Print(); |
-#endif |
- code->Disassemble(GetName()); |
- PrintF("\n"); |
- } |
-#endif |
- |
- if (custom_cache) { |
- SetCustomCache(*code); |
+ if (has_custom_cache()) { |
+ SetCustomCache(*new_object); |
} else { |
// Update the dictionary and the root in Heap. |
Handle<NumberDictionary> dict = |
Factory::DictionaryAtNumberPut( |
Handle<NumberDictionary>(Heap::code_stubs()), |
- key, |
- code); |
+ GetKey(), |
+ new_object); |
Heap::public_set_code_stubs(*dict); |
} |
- result = *code; |
+ code = *new_object; |
} |
- return Handle<Code>(result); |
+ return Handle<Code>(code); |
} |
+Object* CodeStub::TryGetCode() { |
+ Code* code; |
+ if (!FindCodeInCache(&code)) { |
+ // Generate the new code. |
+ MacroAssembler masm(NULL, 256); |
+ GenerateCode(&masm); |
+ |
+ // Create the code object. |
+ CodeDesc desc; |
+ masm.GetCode(&desc); |
+ |
+ // Try to copy the generated code into a heap object. |
+ Code::Flags flags = Code::ComputeFlags(Code::STUB, InLoop()); |
+ Object* new_object = |
+ Heap::CreateCode(desc, NULL, flags, masm.CodeObject()); |
+ if (new_object->IsFailure()) return new_object; |
+ code = Code::cast(new_object); |
+ RecordCodeGeneration(code, &masm); |
+ |
+ if (has_custom_cache()) { |
+ SetCustomCache(code); |
+ } else { |
+ // Try to update the code cache but do not fail if unable. |
+ new_object = Heap::code_stubs()->AtNumberPut(GetKey(), code); |
+ if (!new_object->IsFailure()) { |
+ Heap::public_set_code_stubs(NumberDictionary::cast(new_object)); |
+ } |
+ } |
+ } |
+ |
+ return code; |
+} |
+ |
+ |
const char* CodeStub::MajorName(CodeStub::Major major_key) { |
switch (major_key) { |
#define DEF_CASE(name) case name: return #name; |