Merge V8 at 3.7.12.28

Bug: 5688872

Change-Id: Iddb40cae44d51a2b449f2858951e0472771f5981
diff --git a/src/code-stubs.cc b/src/code-stubs.cc
index 724445e..ba7df80 100644
--- a/src/code-stubs.cc
+++ b/src/code-stubs.cc
@@ -40,7 +40,7 @@
 bool CodeStub::FindCodeInCache(Code** code_out) {
   Heap* heap = Isolate::Current()->heap();
   int index = heap->code_stubs()->FindEntry(GetKey());
-  if (index != UnseededNumberDictionary::kNotFound) {
+  if (index != NumberDictionary::kNotFound) {
     *code_out = Code::cast(heap->code_stubs()->ValueAt(index));
     return true;
   }
@@ -52,11 +52,12 @@
   // Update the static counter each time a new code stub is generated.
   masm->isolate()->counters()->code_stubs()->Increment();
 
-  // Nested stubs are not allowed for leafs.
-  AllowStubCallsScope allow_scope(masm, AllowsStubCalls());
+  // Nested stubs are not allowed for leaves.
+  AllowStubCallsScope allow_scope(masm, false);
 
   // Generate the code for the stub.
   masm->set_generating_stub(true);
+  NoCurrentFrameScope scope(masm);
   Generate(masm);
 }
 
@@ -118,17 +119,19 @@
     Handle<Code> new_object = factory->NewCode(
         desc, flags, masm.CodeObject(), NeedsImmovableCode());
     RecordCodeGeneration(*new_object, &masm);
-    FinishCode(*new_object);
+    FinishCode(new_object);
 
     // Update the dictionary and the root in Heap.
-    Handle<UnseededNumberDictionary> dict =
+    Handle<NumberDictionary> dict =
         factory->DictionaryAtNumberPut(
-            Handle<UnseededNumberDictionary>(heap->code_stubs()),
+            Handle<NumberDictionary>(heap->code_stubs()),
             GetKey(),
             new_object);
     heap->public_set_code_stubs(*dict);
-
     code = *new_object;
+    Activate(code);
+  } else {
+    CHECK(IsPregenerated() == code->is_pregenerated());
   }
 
   ASSERT(!NeedsImmovableCode() || heap->lo_space()->Contains(code));
@@ -136,43 +139,6 @@
 }
 
 
-MaybeObject* CodeStub::TryGetCode() {
-  Code* code;
-  if (!FindCodeInCache(&code)) {
-    // Generate the new code.
-    MacroAssembler masm(Isolate::Current(), NULL, 256);
-    GenerateCode(&masm);
-    Heap* heap = masm.isolate()->heap();
-
-    // Create the code object.
-    CodeDesc desc;
-    masm.GetCode(&desc);
-
-    // Try to copy the generated code into a heap object.
-    Code::Flags flags = Code::ComputeFlags(
-        static_cast<Code::Kind>(GetCodeKind()),
-        GetICState());
-    Object* new_object;
-    { MaybeObject* maybe_new_object =
-          heap->CreateCode(desc, flags, masm.CodeObject());
-      if (!maybe_new_object->ToObject(&new_object)) return maybe_new_object;
-    }
-    code = Code::cast(new_object);
-    RecordCodeGeneration(code, &masm);
-    FinishCode(code);
-
-    // Try to update the code cache but do not fail if unable.
-    MaybeObject* maybe_new_object =
-        heap->code_stubs()->AtNumberPut(GetKey(), code);
-    if (maybe_new_object->ToObject(&new_object)) {
-      heap->public_set_code_stubs(UnseededNumberDictionary::cast(new_object));
-    }
-  }
-
-  return code;
-}
-
-
 const char* CodeStub::MajorName(CodeStub::Major major_key,
                                 bool allow_unknown_keys) {
   switch (major_key) {
@@ -188,6 +154,11 @@
 }
 
 
+void CodeStub::PrintName(StringStream* stream) {
+  stream->Add("%s", MajorName(MajorKey(), false));
+}
+
+
 int ICCompareStub::MinorKey() {
   return OpField::encode(op_ - Token::EQ) | StateField::encode(state_);
 }
@@ -242,9 +213,18 @@
 }
 
 
+void JSEntryStub::FinishCode(Handle<Code> code) {
+  Handle<FixedArray> handler_table =
+      code->GetIsolate()->factory()->NewFixedArray(1, TENURED);
+  handler_table->set(0, Smi::FromInt(handler_offset_));
+  code->set_handler_table(*handler_table);
+}
+
+
 void KeyedLoadElementStub::Generate(MacroAssembler* masm) {
   switch (elements_kind_) {
     case FAST_ELEMENTS:
+    case FAST_SMI_ONLY_ELEMENTS:
       KeyedLoadStubCompiler::GenerateLoadFastElement(masm);
       break;
     case FAST_DOUBLE_ELEMENTS:
@@ -274,7 +254,11 @@
 void KeyedStoreElementStub::Generate(MacroAssembler* masm) {
   switch (elements_kind_) {
     case FAST_ELEMENTS:
-      KeyedStoreStubCompiler::GenerateStoreFastElement(masm, is_js_array_);
+    case FAST_SMI_ONLY_ELEMENTS: {
+      KeyedStoreStubCompiler::GenerateStoreFastElement(masm,
+                                                       is_js_array_,
+                                                       elements_kind_);
+    }
       break;
     case FAST_DOUBLE_ELEMENTS:
       KeyedStoreStubCompiler::GenerateStoreFastDoubleElement(masm,
@@ -302,24 +286,20 @@
 
 
 void ArgumentsAccessStub::PrintName(StringStream* stream) {
-  const char* type_name = NULL;  // Make g++ happy.
+  stream->Add("ArgumentsAccessStub_");
   switch (type_) {
-    case READ_ELEMENT: type_name = "ReadElement"; break;
-    case NEW_NON_STRICT_FAST: type_name = "NewNonStrictFast"; break;
-    case NEW_NON_STRICT_SLOW: type_name = "NewNonStrictSlow"; break;
-    case NEW_STRICT: type_name = "NewStrict"; break;
+    case READ_ELEMENT: stream->Add("ReadElement"); break;
+    case NEW_NON_STRICT_FAST: stream->Add("NewNonStrictFast"); break;
+    case NEW_NON_STRICT_SLOW: stream->Add("NewNonStrictSlow"); break;
+    case NEW_STRICT: stream->Add("NewStrict"); break;
   }
-  stream->Add("ArgumentsAccessStub_%s", type_name);
 }
 
 
 void CallFunctionStub::PrintName(StringStream* stream) {
-  const char* flags_name = NULL;  // Make g++ happy.
-  switch (flags_) {
-    case NO_CALL_FUNCTION_FLAGS: flags_name = ""; break;
-    case RECEIVER_MIGHT_BE_IMPLICIT: flags_name = "_Implicit"; break;
-  }
-  stream->Add("CallFunctionStub_Args%d%s", argc_, flags_name);
+  stream->Add("CallFunctionStub_Args%d", argc_);
+  if (ReceiverMightBeImplicit()) stream->Add("_Implicit");
+  if (RecordCallTarget()) stream->Add("_Recording");
 }
 
 
@@ -402,4 +382,29 @@
 }
 
 
+void ElementsTransitionAndStoreStub::Generate(MacroAssembler* masm) {
+  Label fail;
+  if (!FLAG_trace_elements_transitions) {
+    if (to_ == FAST_ELEMENTS) {
+      if (from_ == FAST_SMI_ONLY_ELEMENTS) {
+        ElementsTransitionGenerator::GenerateSmiOnlyToObject(masm);
+      } else if (from_ == FAST_DOUBLE_ELEMENTS) {
+        ElementsTransitionGenerator::GenerateDoubleToObject(masm, &fail);
+      } else {
+        UNREACHABLE();
+      }
+      KeyedStoreStubCompiler::GenerateStoreFastElement(masm,
+                                                       is_jsarray_,
+                                                       FAST_ELEMENTS);
+    } else if (from_ == FAST_SMI_ONLY_ELEMENTS && to_ == FAST_DOUBLE_ELEMENTS) {
+      ElementsTransitionGenerator::GenerateSmiOnlyToDouble(masm, &fail);
+      KeyedStoreStubCompiler::GenerateStoreFastDoubleElement(masm, is_jsarray_);
+    } else {
+      UNREACHABLE();
+    }
+  }
+  masm->bind(&fail);
+  KeyedStoreIC::GenerateRuntimeSetProperty(masm, strict_mode_);
+}
+
 } }  // namespace v8::internal