| 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;
|
|
|