Introduce LiteralsArray to hide it's implementation.
authormvstanton <mvstanton@chromium.org>
Tue, 29 Sep 2015 10:15:31 +0000 (03:15 -0700)
committerCommit bot <commit-bot@chromium.org>
Tue, 29 Sep 2015 10:15:39 +0000 (10:15 +0000)
The LiteralsArray will soon hold a type feedback vector. Code treats it as an
ordinary fixed array, and needs to stop that.

BUG=

Review URL: https://codereview.chromium.org/1374723002

Cr-Commit-Position: refs/heads/master@{#31000}

25 files changed:
src/arm/lithium-codegen-arm.cc
src/arm64/lithium-codegen-arm64.cc
src/code-stubs-hydrogen.cc
src/compiler.cc
src/debug/liveedit.cc
src/factory.cc
src/full-codegen/arm/full-codegen-arm.cc
src/full-codegen/arm64/full-codegen-arm64.cc
src/full-codegen/ia32/full-codegen-ia32.cc
src/full-codegen/mips/full-codegen-mips.cc
src/full-codegen/mips64/full-codegen-mips64.cc
src/full-codegen/x64/full-codegen-x64.cc
src/hydrogen.cc
src/ia32/lithium-codegen-ia32.cc
src/mips/lithium-codegen-mips.cc
src/mips64/lithium-codegen-mips64.cc
src/objects-inl.h
src/objects.cc
src/objects.h
src/runtime/runtime-function.cc
src/runtime/runtime-literals.cc
src/runtime/runtime-regexp.cc
src/runtime/runtime.h
src/x64/lithium-codegen-x64.cc
test/cctest/test-heap.cc

index bee45d726148a1ca6868d2a79719da6ad7b335bc..d958405e82c2ac6759a49be03f5c132f6277c285 100644 (file)
@@ -5398,7 +5398,7 @@ void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) {
   // r0 = regexp literal clone.
   // r2-5 are used as temporaries.
   int literal_offset =
-      FixedArray::OffsetOfElementAt(instr->hydrogen()->literal_index());
+      LiteralsArray::OffsetOfLiteralAt(instr->hydrogen()->literal_index());
   __ Move(r6, instr->hydrogen()->literals());
   __ ldr(r1, FieldMemOperand(r6, literal_offset));
   __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
index 29192756e5d6bd3566f8b03510a5f3543b62a8fc..29858bb7a8358d8e5d0fab5299d4e62e3d38f2db 100644 (file)
@@ -5648,7 +5648,7 @@ void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) {
   // x0 = regexp literal clone.
   // x10-x12 are used as temporaries.
   int literal_offset =
-      FixedArray::OffsetOfElementAt(instr->hydrogen()->literal_index());
+      LiteralsArray::OffsetOfLiteralAt(instr->hydrogen()->literal_index());
   __ LoadObject(x7, instr->hydrogen()->literals());
   __ Ldr(x1, FieldMemOperand(x7, literal_offset));
   __ JumpIfNotRoot(x1, Heap::kUndefinedValueRootIndex, &materialized);
index 9f782225c1614648c95537e68bc08eb4ec7f0598..dc2ae554bfcf801dd653a8bf81de8cf65a03723a 100644 (file)
@@ -442,8 +442,9 @@ HValue* CodeStubGraphBuilder<FastCloneShallowArrayStub>::BuildCodeStub() {
   // so that it doesn't build and eager frame.
   info()->MarkMustNotHaveEagerFrame();
 
-  HInstruction* allocation_site =
-      Add<HLoadKeyed>(GetParameter(0), GetParameter(1), nullptr, FAST_ELEMENTS);
+  HInstruction* allocation_site = Add<HLoadKeyed>(
+      GetParameter(0), GetParameter(1), nullptr, FAST_ELEMENTS,
+      NEVER_RETURN_HOLE, LiteralsArray::kOffsetToFirstLiteral - kHeapObjectTag);
   IfBuilder checker(this);
   checker.IfNot<HCompareObjectEqAndBranch, HValue*>(allocation_site,
                                                     undefined);
@@ -504,8 +505,9 @@ template <>
 HValue* CodeStubGraphBuilder<FastCloneShallowObjectStub>::BuildCodeStub() {
   HValue* undefined = graph()->GetConstantUndefined();
 
-  HInstruction* allocation_site =
-      Add<HLoadKeyed>(GetParameter(0), GetParameter(1), nullptr, FAST_ELEMENTS);
+  HInstruction* allocation_site = Add<HLoadKeyed>(
+      GetParameter(0), GetParameter(1), nullptr, FAST_ELEMENTS,
+      NEVER_RETURN_HOLE, LiteralsArray::kOffsetToFirstLiteral - kHeapObjectTag);
 
   IfBuilder checker(this);
   checker.IfNot<HCompareObjectEqAndBranch, HValue*>(allocation_site,
index 1901cf3f83133ec56d75cce8168a4976c5bb029d..20aa558c3d1e316789bffdf343b37003ff088d87 100644 (file)
@@ -788,7 +788,7 @@ static void InsertCodeIntoOptimizedCodeMap(CompilationInfo* info) {
   // Cache optimized context-specific code.
   if (FLAG_cache_optimized_code) {
     Handle<SharedFunctionInfo> shared(function->shared());
-    Handle<FixedArray> literals(function->literals());
+    Handle<LiteralsArray> literals(function->literals());
     Handle<Context> native_context(function->context()->native_context());
     SharedFunctionInfo::AddToOptimizedCodeMap(shared, native_context, code,
                                               literals, info->osr_ast_id());
index e0419f487948dcd086bcc0575d613d99da2ea881..8a936ac177b76349d8b8bc9b7e199422ba29a3ce 100644 (file)
@@ -995,10 +995,12 @@ class LiteralFixer {
       // collect all functions and fix their literal arrays.
       Handle<FixedArray> function_instances =
           CollectJSFunctions(shared_info, isolate);
+      Handle<TypeFeedbackVector> vector(shared_info->feedback_vector());
+
       for (int i = 0; i < function_instances->length(); i++) {
         Handle<JSFunction> fun(JSFunction::cast(function_instances->get(i)));
-        Handle<FixedArray> new_literals =
-            isolate->factory()->NewFixedArray(new_literal_count);
+        Handle<LiteralsArray> new_literals =
+            LiteralsArray::New(isolate, vector, new_literal_count, TENURED);
         fun->set_literals(*new_literals);
       }
 
index f078c227115fb223769d57a1d344ca880157bdda..8923d071b106278271507a1cf676889274657092 100644 (file)
@@ -1342,7 +1342,9 @@ Handle<JSFunction> Factory::NewFunctionFromSharedFunctionInfo(
 
   } else if (!info->bound()) {
     int number_of_literals = info->num_literals();
-    Handle<FixedArray> literals = NewFixedArray(number_of_literals, pretenure);
+    Handle<LiteralsArray> literals =
+        LiteralsArray::New(isolate(), handle(info->feedback_vector()),
+                           number_of_literals, pretenure);
     result->set_literals(*literals);
     // Cache context-specific literals.
     if (FLAG_cache_optimized_code) {
index d152f9e601bf4abc653faa308564025be174e3e8..d3d53334d4295b493cc6ad40c520532ab6d8067a 100644 (file)
@@ -1498,8 +1498,7 @@ void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
   // r0 = RegExp literal clone
   __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
   __ ldr(r4, FieldMemOperand(r0, JSFunction::kLiteralsOffset));
-  int literal_offset =
-      FixedArray::kHeaderSize + expr->literal_index() * kPointerSize;
+  int literal_offset = LiteralsArray::OffsetOfLiteralAt(expr->literal_index());
   __ ldr(r5, FieldMemOperand(r4, literal_offset));
   __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
   __ cmp(r5, ip);
index 43e2b9f55b5a27c5d2df93b559a46bb3e0e1cc93..b53e8ee6cde133fdefe74dde81723ddaea3cd45c 100644 (file)
@@ -1487,8 +1487,7 @@ void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
   // x0 = RegExp literal clone
   __ Ldr(x10, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
   __ Ldr(x4, FieldMemOperand(x10, JSFunction::kLiteralsOffset));
-  int literal_offset =
-      FixedArray::kHeaderSize + expr->literal_index() * kPointerSize;
+  int literal_offset = LiteralsArray::OffsetOfLiteralAt(expr->literal_index());
   __ Ldr(x5, FieldMemOperand(x4, literal_offset));
   __ JumpIfNotRoot(x5, Heap::kUndefinedValueRootIndex, &materialized);
 
index 28bb36e95be96a2ce6311e4f0e7a63b0c73c45c9..cce73579623257e0d6e234db16162ff9c591e9f1 100644 (file)
@@ -1422,8 +1422,7 @@ void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
   // eax = regexp literal clone.
   __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
   __ mov(ecx, FieldOperand(edi, JSFunction::kLiteralsOffset));
-  int literal_offset =
-      FixedArray::kHeaderSize + expr->literal_index() * kPointerSize;
+  int literal_offset = LiteralsArray::OffsetOfLiteralAt(expr->literal_index());
   __ mov(ebx, FieldOperand(ecx, literal_offset));
   __ cmp(ebx, isolate()->factory()->undefined_value());
   __ j(not_equal, &materialized, Label::kNear);
index dd5ab55b253e1915eb8a182e9f7aa5b54dacf17f..f38c01bbeaa0cc36275a9bf83c31c97d8388da1d 100644 (file)
@@ -1497,8 +1497,7 @@ void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
   // a0 = RegExp literal clone
   __ lw(a0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
   __ lw(t0, FieldMemOperand(a0, JSFunction::kLiteralsOffset));
-  int literal_offset =
-      FixedArray::kHeaderSize + expr->literal_index() * kPointerSize;
+  int literal_offset = LiteralsArray::OffsetOfLiteralAt(expr->literal_index());
   __ lw(t1, FieldMemOperand(t0, literal_offset));
   __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
   __ Branch(&materialized, ne, t1, Operand(at));
index 68e1c08559553299d6adf156f5811d249b812b25..dcdff515ef5a5b090a384d0d3548b42dba1ee36b 100644 (file)
@@ -1495,8 +1495,7 @@ void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
   // a0 = RegExp literal clone
   __ ld(a0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
   __ ld(a4, FieldMemOperand(a0, JSFunction::kLiteralsOffset));
-  int literal_offset =
-      FixedArray::kHeaderSize + expr->literal_index() * kPointerSize;
+  int literal_offset = LiteralsArray::OffsetOfLiteralAt(expr->literal_index());
   __ ld(a5, FieldMemOperand(a4, literal_offset));
   __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
   __ Branch(&materialized, ne, a5, Operand(at));
index 7662dca268abb9addd8be8d0635341ed3b082c9a..0133c09d6e7d78b618b095073c09f9e05d52cb42 100644 (file)
@@ -1453,8 +1453,7 @@ void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
   // rax = regexp literal clone.
   __ movp(rdi, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
   __ movp(rcx, FieldOperand(rdi, JSFunction::kLiteralsOffset));
-  int literal_offset =
-      FixedArray::kHeaderSize + expr->literal_index() * kPointerSize;
+  int literal_offset = LiteralsArray::OffsetOfLiteralAt(expr->literal_index());
   __ movp(rbx, FieldOperand(rcx, literal_offset));
   __ CompareRoot(rbx, Heap::kUndefinedValueRootIndex);
   __ j(not_equal, &materialized, Label::kNear);
index a55da9d4bd0234016973ccecb1f7ea79295c0480..901e10721d3a02bf5f48d638b2e06ab519ae6835 100644 (file)
@@ -5769,7 +5769,7 @@ void HOptimizedGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) {
   DCHECK(current_block() != NULL);
   DCHECK(current_block()->HasPredecessor());
   Handle<JSFunction> closure = function_state()->compilation_info()->closure();
-  Handle<FixedArray> literals(closure->literals());
+  Handle<LiteralsArray> literals(closure->literals());
   HRegExpLiteral* instr = New<HRegExpLiteral>(literals,
                                               expr->pattern(),
                                               expr->flags(),
@@ -5865,8 +5865,8 @@ void HOptimizedGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
 
   // Check whether to use fast or slow deep-copying for boilerplate.
   int max_properties = kMaxFastLiteralProperties;
-  Handle<Object> literals_cell(closure->literals()->get(expr->literal_index()),
-                               isolate());
+  Handle<Object> literals_cell(
+      closure->literals()->literal(expr->literal_index()), isolate());
   Handle<AllocationSite> site;
   Handle<JSObject> boilerplate;
   if (!literals_cell->IsUndefined()) {
@@ -5884,7 +5884,7 @@ void HOptimizedGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
     site_context.ExitScope(site, boilerplate);
   } else {
     NoObservableSideEffectsScope no_effects(this);
-    Handle<FixedArray> closure_literals(closure->literals(), isolate());
+    Handle<LiteralsArray> closure_literals(closure->literals(), isolate());
     Handle<FixedArray> constant_properties = expr->constant_properties();
     int literal_index = expr->literal_index();
     int flags = expr->ComputeFlags(true);
@@ -5995,9 +5995,10 @@ void HOptimizedGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) {
   HInstruction* literal;
 
   Handle<AllocationSite> site;
-  Handle<FixedArray> literals(environment()->closure()->literals(), isolate());
+  Handle<LiteralsArray> literals(environment()->closure()->literals(),
+                                 isolate());
   bool uninitialized = false;
-  Handle<Object> literals_cell(literals->get(expr->literal_index()),
+  Handle<Object> literals_cell(literals->literal(expr->literal_index()),
                                isolate());
   Handle<JSObject> boilerplate_object;
   if (literals_cell->IsUndefined()) {
@@ -6017,7 +6018,7 @@ void HOptimizedGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) {
       return Bailout(kArrayBoilerplateCreationFailed);
     }
     creation_context.ExitScope(site, boilerplate_object);
-    literals->set(expr->literal_index(), *site);
+    literals->set_literal(expr->literal_index(), *site);
 
     if (boilerplate_object->elements()->map() ==
         isolate()->heap()->fixed_cow_array_map()) {
index 6d33f6d0c9133217a3ad3bffd112d37155f8d0ab..850c182144f797d4f624af3c7350629d5e9abb0f 100644 (file)
@@ -5281,7 +5281,7 @@ void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) {
   // eax = regexp literal clone.
   // esi = context.
   int literal_offset =
-      FixedArray::OffsetOfElementAt(instr->hydrogen()->literal_index());
+      LiteralsArray::OffsetOfLiteralAt(instr->hydrogen()->literal_index());
   __ LoadHeapObject(ecx, instr->hydrogen()->literals());
   __ mov(ebx, FieldOperand(ecx, literal_offset));
   __ cmp(ebx, factory()->undefined_value());
index 7d44fdef2ce155e178d8a5bb30507e86f0cbd9d9..bf158b4c43a9da0713a86b625d9be2e148e53f9a 100644 (file)
@@ -5414,7 +5414,7 @@ void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) {
   // a0 = regexp literal clone.
   // a2 and t0-t2 are used as temporaries.
   int literal_offset =
-      FixedArray::OffsetOfElementAt(instr->hydrogen()->literal_index());
+      LiteralsArray::OffsetOfLiteralAt(instr->hydrogen()->literal_index());
   __ li(t3, instr->hydrogen()->literals());
   __ lw(a1, FieldMemOperand(t3, literal_offset));
   __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
index 6c7b7e1151284a79de1d6d24adaec3fb0ab24880..014847e36c7b11d79d91ec9d6994e91f12fdfdd1 100644 (file)
@@ -5599,7 +5599,7 @@ void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) {
   // a0 = regexp literal clone.
   // a2 and a4-a6 are used as temporaries.
   int literal_offset =
-      FixedArray::OffsetOfElementAt(instr->hydrogen()->literal_index());
+      LiteralsArray::OffsetOfLiteralAt(instr->hydrogen()->literal_index());
   __ li(a7, instr->hydrogen()->literals());
   __ ld(a1, FieldMemOperand(a7, literal_offset));
   __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
index 511d303f9046edf3f975c300346f1343b3c2f2eb..3d39278cce9bd49437e76764f577900cdedb9ad0 100644 (file)
@@ -730,6 +730,9 @@ bool Object::IsTransitionArray() const {
 bool Object::IsTypeFeedbackVector() const { return IsFixedArray(); }
 
 
+bool Object::IsLiteralsArray() const { return IsFixedArray(); }
+
+
 bool Object::IsDeoptimizationInputData() const {
   // Must be a fixed array.
   if (!IsFixedArray()) return false;
@@ -3454,6 +3457,55 @@ void DeoptimizationOutputData::SetPcAndState(int index, Smi* offset) {
 }
 
 
+Object* LiteralsArray::get(int index) const { return FixedArray::get(index); }
+
+
+void LiteralsArray::set(int index, Object* value) {
+  FixedArray::set(index, value);
+}
+
+
+void LiteralsArray::set(int index, Smi* value) {
+  FixedArray::set(index, value);
+}
+
+
+void LiteralsArray::set(int index, Object* value, WriteBarrierMode mode) {
+  FixedArray::set(index, value, mode);
+}
+
+
+LiteralsArray* LiteralsArray::cast(Object* object) {
+  SLOW_DCHECK(object->IsLiteralsArray());
+  return reinterpret_cast<LiteralsArray*>(object);
+}
+
+
+TypeFeedbackVector* LiteralsArray::feedback_vector() const {
+  return TypeFeedbackVector::cast(get(kVectorIndex));
+}
+
+
+void LiteralsArray::set_feedback_vector(TypeFeedbackVector* vector) {
+  set(kVectorIndex, vector);
+}
+
+
+Object* LiteralsArray::literal(int literal_index) const {
+  return get(kFirstLiteralIndex + literal_index);
+}
+
+
+void LiteralsArray::set_literal(int literal_index, Object* literal) {
+  set(kFirstLiteralIndex + literal_index, literal);
+}
+
+
+int LiteralsArray::literals_count() const {
+  return length() - kFirstLiteralIndex;
+}
+
+
 void HandlerTable::SetRangeStart(int index, int value) {
   set(index * kRangeEntrySize + kRangeStartIndex, Smi::FromInt(value));
 }
@@ -6258,13 +6310,13 @@ bool JSFunction::has_simple_parameters() {
 }
 
 
-FixedArray* JSFunction::literals() {
+LiteralsArray* JSFunction::literals() {
   DCHECK(!shared()->bound());
-  return literals_or_bindings();
+  return LiteralsArray::cast(literals_or_bindings());
 }
 
 
-void JSFunction::set_literals(FixedArray* literals) {
+void JSFunction::set_literals(LiteralsArray* literals) {
   DCHECK(!shared()->bound());
   set_literals_or_bindings(literals);
 }
index ca941ce4e21a0c6c0a6b6eb9cc54e8ffd3441054..b6c40d67fe8a64c13d4f7b44779e47281956a306 100644 (file)
@@ -8782,6 +8782,19 @@ Handle<DeoptimizationOutputData> DeoptimizationOutputData::New(
 }
 
 
+// static
+Handle<LiteralsArray> LiteralsArray::New(Isolate* isolate,
+                                         Handle<TypeFeedbackVector> vector,
+                                         int number_of_literals,
+                                         PretenureFlag pretenure) {
+  Handle<FixedArray> literals = isolate->factory()->NewFixedArray(
+      number_of_literals + kFirstLiteralIndex, pretenure);
+  Handle<LiteralsArray> casted_literals = Handle<LiteralsArray>::cast(literals);
+  casted_literals->set_feedback_vector(*vector);
+  return casted_literals;
+}
+
+
 int HandlerTable::LookupRange(int pc_offset, int* stack_depth_out,
                               CatchPrediction* prediction_out) {
   int innermost_handler = -1, innermost_start = -1;
@@ -10191,7 +10204,7 @@ void SharedFunctionInfo::AddSharedCodeToOptimizedCodeMap(
 
 void SharedFunctionInfo::AddToOptimizedCodeMap(
     Handle<SharedFunctionInfo> shared, Handle<Context> native_context,
-    Handle<HeapObject> code, Handle<FixedArray> literals,
+    Handle<HeapObject> code, Handle<LiteralsArray> literals,
     BailoutId osr_ast_id) {
   Isolate* isolate = shared->GetIsolate();
   DCHECK(*code == isolate->heap()->undefined_value() ||
@@ -11381,7 +11394,7 @@ CodeAndLiterals SharedFunctionInfo::SearchOptimizedCodeMap(
       DCHECK_LE(entry + kEntryLength, code_map->length());
       Object* code = code_map->get(entry + kCachedCodeOffset);
       result = {code->IsUndefined() ? nullptr : Code::cast(code),
-                FixedArray::cast(code_map->get(entry + kLiteralsOffset))};
+                LiteralsArray::cast(code_map->get(entry + kLiteralsOffset))};
     }
   }
   if (FLAG_trace_opt && !optimized_code_map()->IsSmi() &&
index 7ea36cc4545d4a7c5f76c9d1394075fc81892791..225a7db42e0cfab92c786cea07095731304ffa22 100644 (file)
@@ -76,6 +76,7 @@
 //       - BytecodeArray
 //       - FixedArray
 //         - DescriptorArray
+//         - LiteralsArray
 //         - HashTable
 //           - Dictionary
 //           - StringTable
@@ -852,6 +853,7 @@ class FunctionLiteral;
 class GlobalObject;
 class JSBuiltinsObject;
 class LayoutDescriptor;
+class LiteralsArray;
 class LookupIterator;
 class ObjectHashTable;
 class ObjectVisitor;
@@ -940,6 +942,7 @@ template <class C> inline bool Is(Object* obj);
   V(Map)                           \
   V(DescriptorArray)               \
   V(TransitionArray)               \
+  V(LiteralsArray)                 \
   V(TypeFeedbackVector)            \
   V(DeoptimizationInputData)       \
   V(DeoptimizationOutputData)      \
@@ -4568,6 +4571,40 @@ class DeoptimizationOutputData: public FixedArray {
 };
 
 
+// A literals array contains the literals for a JSFunction. It also holds
+// the type feedback vector.
+class LiteralsArray : public FixedArray {
+ public:
+  static const int kVectorIndex = 0;
+  static const int kFirstLiteralIndex = 1;
+  static const int kOffsetToFirstLiteral =
+      FixedArray::kHeaderSize + kPointerSize;
+
+  static int OffsetOfLiteralAt(int index) {
+    return SizeFor(index + kFirstLiteralIndex);
+  }
+
+  inline TypeFeedbackVector* feedback_vector() const;
+  inline void set_feedback_vector(TypeFeedbackVector* vector);
+  inline Object* literal(int literal_index) const;
+  inline void set_literal(int literal_index, Object* literal);
+  inline int literals_count() const;
+
+  static Handle<LiteralsArray> New(Isolate* isolate,
+                                   Handle<TypeFeedbackVector> vector,
+                                   int number_of_literals,
+                                   PretenureFlag pretenure);
+
+  DECLARE_CAST(LiteralsArray)
+
+ private:
+  inline Object* get(int index) const;
+  inline void set(int index, Object* value);
+  inline void set(int index, Smi* value);
+  inline void set(int index, Object* value, WriteBarrierMode mode);
+};
+
+
 // HandlerTable is a fixed array containing entries for exception handlers in
 // the code object it is associated with. The tables comes in two flavors:
 // 1) Based on ranges: Used for unoptimized code. Contains one entry per
@@ -6292,7 +6329,7 @@ enum BuiltinFunctionId {
 // that both {code} and {literals} can be NULL to pass search result status.
 struct CodeAndLiterals {
   Code* code;            // Cached optimized code.
-  FixedArray* literals;  // Cached literals array.
+  LiteralsArray* literals;  // Cached literals array.
 };
 
 
@@ -6339,7 +6376,7 @@ class SharedFunctionInfo: public HeapObject {
   static void AddToOptimizedCodeMap(Handle<SharedFunctionInfo> shared,
                                     Handle<Context> native_context,
                                     Handle<HeapObject> code,
-                                    Handle<FixedArray> literals,
+                                    Handle<LiteralsArray> literals,
                                     BailoutId osr_ast_id);
 
   // Set up the link between shared function info and the script. The shared
@@ -7135,8 +7172,8 @@ class JSFunction: public JSObject {
   // arguments. Bound functions never contain literals.
   DECL_ACCESSORS(literals_or_bindings, FixedArray)
 
-  inline FixedArray* literals();
-  inline void set_literals(FixedArray* literals);
+  inline LiteralsArray* literals();
+  inline void set_literals(LiteralsArray* literals);
 
   inline FixedArray* function_bindings();
   inline void set_function_bindings(FixedArray* bindings);
index 71c4812f4c8a16efc678042145afb3119a30e30c..966d50c9490eb9e6578bf7766bc0c8b29a8ce390 100644 (file)
@@ -236,10 +236,12 @@ RUNTIME_FUNCTION(Runtime_SetCode) {
   // Make sure we get a fresh copy of the literal vector to avoid cross
   // context contamination.
   Handle<Context> context(source->context());
-  int number_of_literals = source->NumberOfLiterals();
-  Handle<FixedArray> literals =
-      isolate->factory()->NewFixedArray(number_of_literals, TENURED);
   target->set_context(*context);
+
+  int number_of_literals = source->NumberOfLiterals();
+  Handle<LiteralsArray> literals =
+      LiteralsArray::New(isolate, handle(target_shared->feedback_vector()),
+                         number_of_literals, TENURED);
   target->set_literals(*literals);
 
   if (isolate->logger()->is_logging_code_events() ||
index 113193835d9852765363f1fb529ea657c8bb39f8..903e2feb53b1d2deb5b4f0e4bda56237b326b414 100644 (file)
@@ -34,12 +34,12 @@ static Handle<Map> ComputeObjectLiteralMap(
 }
 
 MUST_USE_RESULT static MaybeHandle<Object> CreateLiteralBoilerplate(
-    Isolate* isolate, Handle<FixedArray> literals,
+    Isolate* isolate, Handle<LiteralsArray> literals,
     Handle<FixedArray> constant_properties, bool is_strong);
 
 
 MUST_USE_RESULT static MaybeHandle<Object> CreateObjectLiteralBoilerplate(
-    Isolate* isolate, Handle<FixedArray> literals,
+    Isolate* isolate, Handle<LiteralsArray> literals,
     Handle<FixedArray> constant_properties, bool should_have_fast_elements,
     bool has_function_literal, bool is_strong) {
   Handle<Context> context = isolate->native_context();
@@ -139,7 +139,7 @@ MUST_USE_RESULT static MaybeHandle<Object> CreateObjectLiteralBoilerplate(
 
 
 MaybeHandle<Object> Runtime::CreateArrayLiteralBoilerplate(
-    Isolate* isolate, Handle<FixedArray> literals,
+    Isolate* isolate, Handle<LiteralsArray> literals,
     Handle<FixedArray> elements, bool is_strong) {
   // Create the JSArray.
   Handle<JSFunction> constructor = isolate->array_function();
@@ -215,7 +215,7 @@ MaybeHandle<Object> Runtime::CreateArrayLiteralBoilerplate(
 
 
 MUST_USE_RESULT static MaybeHandle<Object> CreateLiteralBoilerplate(
-    Isolate* isolate, Handle<FixedArray> literals, Handle<FixedArray> array,
+    Isolate* isolate, Handle<LiteralsArray> literals, Handle<FixedArray> array,
     bool is_strong) {
   Handle<FixedArray> elements = CompileTimeValue::GetElements(array);
   const bool kHasNoFunctionLiteral = false;
@@ -239,7 +239,7 @@ MUST_USE_RESULT static MaybeHandle<Object> CreateLiteralBoilerplate(
 RUNTIME_FUNCTION(Runtime_CreateObjectLiteral) {
   HandleScope scope(isolate);
   DCHECK(args.length() == 4);
-  CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
+  CONVERT_ARG_HANDLE_CHECKED(LiteralsArray, literals, 0);
   CONVERT_SMI_ARG_CHECKED(literals_index, 1);
   CONVERT_ARG_HANDLE_CHECKED(FixedArray, constant_properties, 2);
   CONVERT_SMI_ARG_CHECKED(flags, 3);
@@ -248,10 +248,11 @@ RUNTIME_FUNCTION(Runtime_CreateObjectLiteral) {
   bool enable_mementos = (flags & ObjectLiteral::kDisableMementos) == 0;
   bool is_strong = (flags & ObjectLiteral::kIsStrong) != 0;
 
-  RUNTIME_ASSERT(literals_index >= 0 && literals_index < literals->length());
+  RUNTIME_ASSERT(literals_index >= 0 &&
+                 literals_index < literals->literals_count());
 
   // Check if boilerplate exists. If not, create it first.
-  Handle<Object> literal_site(literals->get(literals_index), isolate);
+  Handle<Object> literal_site(literals->literal(literals_index), isolate);
   Handle<AllocationSite> site;
   Handle<JSObject> boilerplate;
   if (*literal_site == isolate->heap()->undefined_value()) {
@@ -270,7 +271,7 @@ RUNTIME_FUNCTION(Runtime_CreateObjectLiteral) {
     creation_context.ExitScope(site, boilerplate);
 
     // Update the functions literal and return the boilerplate.
-    literals->set(literals_index, *site);
+    literals->set_literal(literals_index, *site);
   } else {
     site = Handle<AllocationSite>::cast(literal_site);
     boilerplate =
@@ -289,10 +290,10 @@ RUNTIME_FUNCTION(Runtime_CreateObjectLiteral) {
 
 
 MUST_USE_RESULT static MaybeHandle<AllocationSite> GetLiteralAllocationSite(
-    Isolate* isolate, Handle<FixedArray> literals, int literals_index,
+    Isolate* isolate, Handle<LiteralsArray> literals, int literals_index,
     Handle<FixedArray> elements, bool is_strong) {
   // Check if boilerplate exists. If not, create it first.
-  Handle<Object> literal_site(literals->get(literals_index), isolate);
+  Handle<Object> literal_site(literals->literal(literals_index), isolate);
   Handle<AllocationSite> site;
   if (*literal_site == isolate->heap()->undefined_value()) {
     DCHECK(*elements != isolate->heap()->empty_fixed_array());
@@ -311,7 +312,7 @@ MUST_USE_RESULT static MaybeHandle<AllocationSite> GetLiteralAllocationSite(
     }
     creation_context.ExitScope(site, Handle<JSObject>::cast(boilerplate));
 
-    literals->set(literals_index, *site);
+    literals->set_literal(literals_index, *site);
   } else {
     site = Handle<AllocationSite>::cast(literal_site);
   }
@@ -320,13 +321,12 @@ MUST_USE_RESULT static MaybeHandle<AllocationSite> GetLiteralAllocationSite(
 }
 
 
-static MaybeHandle<JSObject> CreateArrayLiteralImpl(Isolate* isolate,
-                                                    Handle<FixedArray> literals,
-                                                    int literals_index,
-                                                    Handle<FixedArray> elements,
-                                                    int flags) {
+static MaybeHandle<JSObject> CreateArrayLiteralImpl(
+    Isolate* isolate, Handle<LiteralsArray> literals, int literals_index,
+    Handle<FixedArray> elements, int flags) {
   RUNTIME_ASSERT_HANDLIFIED(
-      literals_index >= 0 && literals_index < literals->length(), JSObject);
+      literals_index >= 0 && literals_index < literals->literals_count(),
+      JSObject);
   Handle<AllocationSite> site;
   bool is_strong = (flags & ArrayLiteral::kIsStrong) != 0;
   ASSIGN_RETURN_ON_EXCEPTION(
@@ -352,7 +352,7 @@ static MaybeHandle<JSObject> CreateArrayLiteralImpl(Isolate* isolate,
 RUNTIME_FUNCTION(Runtime_CreateArrayLiteral) {
   HandleScope scope(isolate);
   DCHECK(args.length() == 4);
-  CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
+  CONVERT_ARG_HANDLE_CHECKED(LiteralsArray, literals, 0);
   CONVERT_SMI_ARG_CHECKED(literals_index, 1);
   CONVERT_ARG_HANDLE_CHECKED(FixedArray, elements, 2);
   CONVERT_SMI_ARG_CHECKED(flags, 3);
@@ -368,7 +368,7 @@ RUNTIME_FUNCTION(Runtime_CreateArrayLiteral) {
 RUNTIME_FUNCTION(Runtime_CreateArrayLiteralStubBailout) {
   HandleScope scope(isolate);
   DCHECK(args.length() == 3);
-  CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
+  CONVERT_ARG_HANDLE_CHECKED(LiteralsArray, literals, 0);
   CONVERT_SMI_ARG_CHECKED(literals_index, 1);
   CONVERT_ARG_HANDLE_CHECKED(FixedArray, elements, 2);
 
@@ -387,10 +387,10 @@ RUNTIME_FUNCTION(Runtime_StoreArrayLiteralElement) {
   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
   CONVERT_SMI_ARG_CHECKED(store_index, 1);
   CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
-  CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 3);
+  CONVERT_ARG_HANDLE_CHECKED(LiteralsArray, literals, 3);
   CONVERT_SMI_ARG_CHECKED(literal_index, 4);
 
-  Object* raw_literal_cell = literals->get(literal_index);
+  Object* raw_literal_cell = literals->literal(literal_index);
   JSArray* boilerplate = NULL;
   if (raw_literal_cell->IsAllocationSite()) {
     AllocationSite* site = AllocationSite::cast(raw_literal_cell);
index acefe0767b3cb1de46eb3882be9f808993817d22..48154ea275122dd8471dc238af2286f85f41ccd9 100644 (file)
@@ -985,7 +985,7 @@ RUNTIME_FUNCTION(Runtime_RegExpInitializeAndCompile) {
 RUNTIME_FUNCTION(Runtime_MaterializeRegExpLiteral) {
   HandleScope scope(isolate);
   DCHECK(args.length() == 4);
-  CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
+  CONVERT_ARG_HANDLE_CHECKED(LiteralsArray, literals, 0);
   CONVERT_SMI_ARG_CHECKED(index, 1);
   CONVERT_ARG_HANDLE_CHECKED(String, pattern, 2);
   CONVERT_ARG_HANDLE_CHECKED(String, flags, 3);
@@ -996,7 +996,7 @@ RUNTIME_FUNCTION(Runtime_MaterializeRegExpLiteral) {
   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
       isolate, regexp,
       RegExpImpl::CreateRegExpLiteral(constructor, pattern, flags));
-  literals->set(index, *regexp);
+  literals->set_literal(index, *regexp);
   return *regexp;
 }
 
index b738f2fed93c91a5c31821416f315f9fa9b553db..6e55d747943f9a7a3ef669e2d02512a5e2371903 100644 (file)
@@ -1212,7 +1212,7 @@ class Runtime : public AllStatic {
 
   // Used in runtime.cc and hydrogen's VisitArrayLiteral.
   MUST_USE_RESULT static MaybeHandle<Object> CreateArrayLiteralBoilerplate(
-      Isolate* isolate, Handle<FixedArray> literals,
+      Isolate* isolate, Handle<LiteralsArray> literals,
       Handle<FixedArray> elements, bool is_strong);
 
   static MaybeHandle<JSArray> GetInternalProperties(Isolate* isolate,
index 81e408717173a408de461d92699bd46b2bf4ce7e..dbdd146a1ebbee7665d265a4667247e033b27419 100644 (file)
@@ -5458,7 +5458,7 @@ void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) {
   // rbx = regexp literal.
   // rax = regexp literal clone.
   int literal_offset =
-      FixedArray::OffsetOfElementAt(instr->hydrogen()->literal_index());
+      LiteralsArray::OffsetOfLiteralAt(instr->hydrogen()->literal_index());
   __ Move(rcx, instr->hydrogen()->literals());
   __ movp(rbx, FieldOperand(rcx, literal_offset));
   __ CompareRoot(rbx, Heap::kUndefinedValueRootIndex);
index 570f48abf1f4cedb446898505e49348b4f4b02fa..6eee9ffbcbfe9e1d7d594a8a110279b939126dc9 100644 (file)
@@ -4464,7 +4464,9 @@ TEST(Regress513507) {
     if (!code->is_optimized_code()) return;
   }
 
-  Handle<FixedArray> lit = isolate->factory()->empty_fixed_array();
+  Handle<TypeFeedbackVector> vector = handle(shared->feedback_vector());
+  Handle<LiteralsArray> lit =
+      LiteralsArray::New(isolate, vector, shared->num_literals(), TENURED);
   Handle<Context> context(isolate->context());
 
   // Add the new code several times to the optimized code map and also set an
@@ -4520,7 +4522,9 @@ TEST(Regress514122) {
     if (!code->is_optimized_code()) return;
   }
 
-  Handle<FixedArray> lit = isolate->factory()->empty_fixed_array();
+  Handle<TypeFeedbackVector> vector = handle(shared->feedback_vector());
+  Handle<LiteralsArray> lit =
+      LiteralsArray::New(isolate, vector, shared->num_literals(), TENURED);
   Handle<Context> context(isolate->context());
 
   // Add the code several times to the optimized code map.
@@ -4538,7 +4542,11 @@ TEST(Regress514122) {
     AlwaysAllocateScope always_allocate(isolate);
     // Make sure literal is placed on an old-space evacuation candidate.
     SimulateFullSpace(heap->old_space());
-    Handle<FixedArray> lit = isolate->factory()->NewFixedArray(23, TENURED);
+
+    // Make sure there the number of literals is > 0.
+    Handle<LiteralsArray> lit =
+        LiteralsArray::New(isolate, vector, 23, TENURED);
+
     evac_page = Page::FromAddress(lit->address());
     BailoutId id = BailoutId(100);
     SharedFunctionInfo::AddToOptimizedCodeMap(shared, context, code, lit, id);