New version of v8 from bleeding edge at revision 3649
diff --git a/src/code-stubs.cc b/src/code-stubs.cc
index dbc39ff..09581aa 100644
--- a/src/code-stubs.cc
+++ b/src/code-stubs.cc
@@ -35,82 +35,117 @@
 namespace v8 {
 namespace internal {
 
-Handle<Code> CodeStub::GetCode() {
-  bool custom_cache = has_custom_cache();
-
-  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)));
+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;
+}
 
-  Code* result;
-  {
+
+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
+}
+
+
+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);
-
-    // 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);
+    GenerateCode(&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;
 }