• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "src/factory.h"
6 
7 #include "src/accessors.h"
8 #include "src/allocation-site-scopes.h"
9 #include "src/ast/ast.h"
10 #include "src/base/bits.h"
11 #include "src/bootstrapper.h"
12 #include "src/compiler.h"
13 #include "src/conversions.h"
14 #include "src/isolate-inl.h"
15 #include "src/macro-assembler.h"
16 #include "src/objects/module-info.h"
17 #include "src/objects/scope-info.h"
18 
19 namespace v8 {
20 namespace internal {
21 
22 
23 // Calls the FUNCTION_CALL function and retries it up to three times
24 // to guarantee that any allocations performed during the call will
25 // succeed if there's enough memory.
26 //
27 // Warning: Do not use the identifiers __object__, __maybe_object__,
28 // __allocation__ or __scope__ in a call to this macro.
29 
30 #define RETURN_OBJECT_UNLESS_RETRY(ISOLATE, TYPE)         \
31   if (__allocation__.To(&__object__)) {                   \
32     DCHECK(__object__ != (ISOLATE)->heap()->exception()); \
33     return Handle<TYPE>(TYPE::cast(__object__), ISOLATE); \
34   }
35 
36 #define CALL_HEAP_FUNCTION(ISOLATE, FUNCTION_CALL, TYPE)                      \
37   do {                                                                        \
38     AllocationResult __allocation__ = FUNCTION_CALL;                          \
39     Object* __object__ = NULL;                                                \
40     RETURN_OBJECT_UNLESS_RETRY(ISOLATE, TYPE)                                 \
41     /* Two GCs before panicking.  In newspace will almost always succeed. */  \
42     for (int __i__ = 0; __i__ < 2; __i__++) {                                 \
43       (ISOLATE)->heap()->CollectGarbage(                                      \
44           __allocation__.RetrySpace(),                                        \
45           GarbageCollectionReason::kAllocationFailure);                       \
46       __allocation__ = FUNCTION_CALL;                                         \
47       RETURN_OBJECT_UNLESS_RETRY(ISOLATE, TYPE)                               \
48     }                                                                         \
49     (ISOLATE)->counters()->gc_last_resort_from_handles()->Increment();        \
50     (ISOLATE)->heap()->CollectAllAvailableGarbage(                            \
51         GarbageCollectionReason::kLastResort);                                \
52     {                                                                         \
53       AlwaysAllocateScope __scope__(ISOLATE);                                 \
54       __allocation__ = FUNCTION_CALL;                                         \
55     }                                                                         \
56     RETURN_OBJECT_UNLESS_RETRY(ISOLATE, TYPE)                                 \
57     /* TODO(1181417): Fix this. */                                            \
58     v8::internal::Heap::FatalProcessOutOfMemory("CALL_AND_RETRY_LAST", true); \
59     return Handle<TYPE>();                                                    \
60   } while (false)
61 
62 template<typename T>
New(Handle<Map> map,AllocationSpace space)63 Handle<T> Factory::New(Handle<Map> map, AllocationSpace space) {
64   CALL_HEAP_FUNCTION(
65       isolate(),
66       isolate()->heap()->Allocate(*map, space),
67       T);
68 }
69 
70 
71 template<typename T>
New(Handle<Map> map,AllocationSpace space,Handle<AllocationSite> allocation_site)72 Handle<T> Factory::New(Handle<Map> map,
73                        AllocationSpace space,
74                        Handle<AllocationSite> allocation_site) {
75   CALL_HEAP_FUNCTION(
76       isolate(),
77       isolate()->heap()->Allocate(*map, space, *allocation_site),
78       T);
79 }
80 
81 
NewFillerObject(int size,bool double_align,AllocationSpace space)82 Handle<HeapObject> Factory::NewFillerObject(int size,
83                                             bool double_align,
84                                             AllocationSpace space) {
85   CALL_HEAP_FUNCTION(
86       isolate(),
87       isolate()->heap()->AllocateFillerObject(size, double_align, space),
88       HeapObject);
89 }
90 
91 
NewPrototypeInfo()92 Handle<PrototypeInfo> Factory::NewPrototypeInfo() {
93   Handle<PrototypeInfo> result =
94       Handle<PrototypeInfo>::cast(NewStruct(PROTOTYPE_INFO_TYPE));
95   result->set_prototype_users(WeakFixedArray::Empty());
96   result->set_registry_slot(PrototypeInfo::UNREGISTERED);
97   result->set_validity_cell(Smi::kZero);
98   result->set_bit_field(0);
99   return result;
100 }
101 
NewTuple2(Handle<Object> value1,Handle<Object> value2)102 Handle<Tuple2> Factory::NewTuple2(Handle<Object> value1,
103                                   Handle<Object> value2) {
104   Handle<Tuple2> result = Handle<Tuple2>::cast(NewStruct(TUPLE2_TYPE));
105   result->set_value1(*value1);
106   result->set_value2(*value2);
107   return result;
108 }
109 
NewTuple3(Handle<Object> value1,Handle<Object> value2,Handle<Object> value3)110 Handle<Tuple3> Factory::NewTuple3(Handle<Object> value1, Handle<Object> value2,
111                                   Handle<Object> value3) {
112   Handle<Tuple3> result = Handle<Tuple3>::cast(NewStruct(TUPLE3_TYPE));
113   result->set_value1(*value1);
114   result->set_value2(*value2);
115   result->set_value3(*value3);
116   return result;
117 }
118 
NewContextExtension(Handle<ScopeInfo> scope_info,Handle<Object> extension)119 Handle<ContextExtension> Factory::NewContextExtension(
120     Handle<ScopeInfo> scope_info, Handle<Object> extension) {
121   Handle<ContextExtension> result =
122       Handle<ContextExtension>::cast(NewStruct(CONTEXT_EXTENSION_TYPE));
123   result->set_scope_info(*scope_info);
124   result->set_extension(*extension);
125   return result;
126 }
127 
NewConstantElementsPair(ElementsKind elements_kind,Handle<FixedArrayBase> constant_values)128 Handle<ConstantElementsPair> Factory::NewConstantElementsPair(
129     ElementsKind elements_kind, Handle<FixedArrayBase> constant_values) {
130   Handle<ConstantElementsPair> result = Handle<ConstantElementsPair>::cast(
131       NewStruct(CONSTANT_ELEMENTS_PAIR_TYPE));
132   result->set_elements_kind(elements_kind);
133   result->set_constant_values(*constant_values);
134   return result;
135 }
136 
NewOddball(Handle<Map> map,const char * to_string,Handle<Object> to_number,const char * type_of,byte kind)137 Handle<Oddball> Factory::NewOddball(Handle<Map> map, const char* to_string,
138                                     Handle<Object> to_number,
139                                     const char* type_of, byte kind) {
140   Handle<Oddball> oddball = New<Oddball>(map, OLD_SPACE);
141   Oddball::Initialize(isolate(), oddball, to_string, to_number, type_of, kind);
142   return oddball;
143 }
144 
145 
NewFixedArray(int size,PretenureFlag pretenure)146 Handle<FixedArray> Factory::NewFixedArray(int size, PretenureFlag pretenure) {
147   DCHECK(0 <= size);
148   CALL_HEAP_FUNCTION(
149       isolate(),
150       isolate()->heap()->AllocateFixedArray(size, pretenure),
151       FixedArray);
152 }
153 
TryNewFixedArray(int size,PretenureFlag pretenure)154 MaybeHandle<FixedArray> Factory::TryNewFixedArray(int size,
155                                                   PretenureFlag pretenure) {
156   DCHECK(0 <= size);
157   AllocationResult allocation =
158       isolate()->heap()->AllocateFixedArray(size, pretenure);
159   Object* array = NULL;
160   if (!allocation.To(&array)) return MaybeHandle<FixedArray>();
161   return Handle<FixedArray>(FixedArray::cast(array), isolate());
162 }
163 
NewFixedArrayWithHoles(int size,PretenureFlag pretenure)164 Handle<FixedArray> Factory::NewFixedArrayWithHoles(int size,
165                                                    PretenureFlag pretenure) {
166   DCHECK(0 <= size);
167   CALL_HEAP_FUNCTION(
168       isolate(),
169       isolate()->heap()->AllocateFixedArrayWithFiller(size,
170                                                       pretenure,
171                                                       *the_hole_value()),
172       FixedArray);
173 }
174 
NewUninitializedFixedArray(int size)175 Handle<FixedArray> Factory::NewUninitializedFixedArray(int size) {
176   CALL_HEAP_FUNCTION(
177       isolate(),
178       isolate()->heap()->AllocateUninitializedFixedArray(size),
179       FixedArray);
180 }
181 
NewBoilerplateDescription(int boilerplate,int all_properties,int index_keys,bool has_seen_proto)182 Handle<BoilerplateDescription> Factory::NewBoilerplateDescription(
183     int boilerplate, int all_properties, int index_keys, bool has_seen_proto) {
184   DCHECK_GE(boilerplate, 0);
185   DCHECK_GE(all_properties, index_keys);
186   DCHECK_GE(index_keys, 0);
187 
188   int backing_store_size =
189       all_properties - index_keys - (has_seen_proto ? 1 : 0);
190   DCHECK_GE(backing_store_size, 0);
191   bool has_different_size_backing_store = boilerplate != backing_store_size;
192 
193   // Space for name and value for every boilerplate property.
194   int size = 2 * boilerplate;
195 
196   if (has_different_size_backing_store) {
197     // An extra entry for the backing store size.
198     size++;
199   }
200 
201   Handle<BoilerplateDescription> description =
202       Handle<BoilerplateDescription>::cast(NewFixedArray(size, TENURED));
203 
204   if (has_different_size_backing_store) {
205     DCHECK((boilerplate != (all_properties - index_keys)) || has_seen_proto);
206     description->set_backing_store_size(isolate(), backing_store_size);
207   }
208   return description;
209 }
210 
NewFixedDoubleArray(int size,PretenureFlag pretenure)211 Handle<FixedArrayBase> Factory::NewFixedDoubleArray(int size,
212                                                     PretenureFlag pretenure) {
213   DCHECK(0 <= size);
214   CALL_HEAP_FUNCTION(
215       isolate(),
216       isolate()->heap()->AllocateUninitializedFixedDoubleArray(size, pretenure),
217       FixedArrayBase);
218 }
219 
220 
NewFixedDoubleArrayWithHoles(int size,PretenureFlag pretenure)221 Handle<FixedArrayBase> Factory::NewFixedDoubleArrayWithHoles(
222     int size,
223     PretenureFlag pretenure) {
224   DCHECK(0 <= size);
225   Handle<FixedArrayBase> array = NewFixedDoubleArray(size, pretenure);
226   if (size > 0) {
227     Handle<FixedDoubleArray>::cast(array)->FillWithHoles(0, size);
228   }
229   return array;
230 }
231 
NewFrameArray(int number_of_frames,PretenureFlag pretenure)232 Handle<FrameArray> Factory::NewFrameArray(int number_of_frames,
233                                           PretenureFlag pretenure) {
234   DCHECK_LE(0, number_of_frames);
235   Handle<FixedArray> result =
236       NewFixedArrayWithHoles(FrameArray::LengthFor(number_of_frames));
237   result->set(FrameArray::kFrameCountIndex, Smi::kZero);
238   return Handle<FrameArray>::cast(result);
239 }
240 
NewOrderedHashSet()241 Handle<OrderedHashSet> Factory::NewOrderedHashSet() {
242   return OrderedHashSet::Allocate(isolate(), OrderedHashSet::kMinCapacity);
243 }
244 
245 
NewOrderedHashMap()246 Handle<OrderedHashMap> Factory::NewOrderedHashMap() {
247   return OrderedHashMap::Allocate(isolate(), OrderedHashMap::kMinCapacity);
248 }
249 
250 
NewAccessorPair()251 Handle<AccessorPair> Factory::NewAccessorPair() {
252   Handle<AccessorPair> accessors =
253       Handle<AccessorPair>::cast(NewStruct(ACCESSOR_PAIR_TYPE));
254   accessors->set_getter(*null_value(), SKIP_WRITE_BARRIER);
255   accessors->set_setter(*null_value(), SKIP_WRITE_BARRIER);
256   return accessors;
257 }
258 
259 
NewTypeFeedbackInfo()260 Handle<TypeFeedbackInfo> Factory::NewTypeFeedbackInfo() {
261   Handle<TypeFeedbackInfo> info =
262       Handle<TypeFeedbackInfo>::cast(NewStruct(TYPE_FEEDBACK_INFO_TYPE));
263   info->initialize_storage();
264   return info;
265 }
266 
267 
268 // Internalized strings are created in the old generation (data space).
InternalizeUtf8String(Vector<const char> string)269 Handle<String> Factory::InternalizeUtf8String(Vector<const char> string) {
270   Utf8StringKey key(string, isolate()->heap()->HashSeed());
271   return InternalizeStringWithKey(&key);
272 }
273 
274 
InternalizeOneByteString(Vector<const uint8_t> string)275 Handle<String> Factory::InternalizeOneByteString(Vector<const uint8_t> string) {
276   OneByteStringKey key(string, isolate()->heap()->HashSeed());
277   return InternalizeStringWithKey(&key);
278 }
279 
280 
InternalizeOneByteString(Handle<SeqOneByteString> string,int from,int length)281 Handle<String> Factory::InternalizeOneByteString(
282     Handle<SeqOneByteString> string, int from, int length) {
283   SeqOneByteSubStringKey key(string, from, length);
284   return InternalizeStringWithKey(&key);
285 }
286 
287 
InternalizeTwoByteString(Vector<const uc16> string)288 Handle<String> Factory::InternalizeTwoByteString(Vector<const uc16> string) {
289   TwoByteStringKey key(string, isolate()->heap()->HashSeed());
290   return InternalizeStringWithKey(&key);
291 }
292 
293 
294 template<class StringTableKey>
InternalizeStringWithKey(StringTableKey * key)295 Handle<String> Factory::InternalizeStringWithKey(StringTableKey* key) {
296   return StringTable::LookupKey(isolate(), key);
297 }
298 
299 
NewStringFromOneByte(Vector<const uint8_t> string,PretenureFlag pretenure)300 MaybeHandle<String> Factory::NewStringFromOneByte(Vector<const uint8_t> string,
301                                                   PretenureFlag pretenure) {
302   int length = string.length();
303   if (length == 0) return empty_string();
304   if (length == 1) return LookupSingleCharacterStringFromCode(string[0]);
305   Handle<SeqOneByteString> result;
306   ASSIGN_RETURN_ON_EXCEPTION(
307       isolate(),
308       result,
309       NewRawOneByteString(string.length(), pretenure),
310       String);
311 
312   DisallowHeapAllocation no_gc;
313   // Copy the characters into the new object.
314   CopyChars(SeqOneByteString::cast(*result)->GetChars(),
315             string.start(),
316             length);
317   return result;
318 }
319 
NewStringFromUtf8(Vector<const char> string,PretenureFlag pretenure)320 MaybeHandle<String> Factory::NewStringFromUtf8(Vector<const char> string,
321                                                PretenureFlag pretenure) {
322   // Check for ASCII first since this is the common case.
323   const char* start = string.start();
324   int length = string.length();
325   int non_ascii_start = String::NonAsciiStart(start, length);
326   if (non_ascii_start >= length) {
327     // If the string is ASCII, we do not need to convert the characters
328     // since UTF8 is backwards compatible with ASCII.
329     return NewStringFromOneByte(Vector<const uint8_t>::cast(string), pretenure);
330   }
331 
332   // Non-ASCII and we need to decode.
333   Access<UnicodeCache::Utf8Decoder>
334       decoder(isolate()->unicode_cache()->utf8_decoder());
335   decoder->Reset(string.start() + non_ascii_start,
336                  length - non_ascii_start);
337   int utf16_length = static_cast<int>(decoder->Utf16Length());
338   DCHECK(utf16_length > 0);
339   // Allocate string.
340   Handle<SeqTwoByteString> result;
341   ASSIGN_RETURN_ON_EXCEPTION(
342       isolate(), result,
343       NewRawTwoByteString(non_ascii_start + utf16_length, pretenure),
344       String);
345   // Copy ASCII portion.
346   uint16_t* data = result->GetChars();
347   const char* ascii_data = string.start();
348   for (int i = 0; i < non_ascii_start; i++) {
349     *data++ = *ascii_data++;
350   }
351   // Now write the remainder.
352   decoder->WriteUtf16(data, utf16_length);
353   return result;
354 }
355 
NewStringFromUtf8SubString(Handle<SeqOneByteString> str,int begin,int length,PretenureFlag pretenure)356 MaybeHandle<String> Factory::NewStringFromUtf8SubString(
357     Handle<SeqOneByteString> str, int begin, int length,
358     PretenureFlag pretenure) {
359   // Check for ASCII first since this is the common case.
360   const char* start = reinterpret_cast<const char*>(str->GetChars() + begin);
361   int non_ascii_start = String::NonAsciiStart(start, length);
362   if (non_ascii_start >= length) {
363     // If the string is ASCII, we can just make a substring.
364     // TODO(v8): the pretenure flag is ignored in this case.
365     return NewSubString(str, begin, begin + length);
366   }
367 
368   // Non-ASCII and we need to decode.
369   Access<UnicodeCache::Utf8Decoder> decoder(
370       isolate()->unicode_cache()->utf8_decoder());
371   decoder->Reset(start + non_ascii_start, length - non_ascii_start);
372   int utf16_length = static_cast<int>(decoder->Utf16Length());
373   DCHECK(utf16_length > 0);
374   // Allocate string.
375   Handle<SeqTwoByteString> result;
376   ASSIGN_RETURN_ON_EXCEPTION(
377       isolate(), result,
378       NewRawTwoByteString(non_ascii_start + utf16_length, pretenure), String);
379 
380   // Reset the decoder, because the original {str} may have moved.
381   const char* ascii_data =
382       reinterpret_cast<const char*>(str->GetChars() + begin);
383   decoder->Reset(ascii_data + non_ascii_start, length - non_ascii_start);
384   // Copy ASCII portion.
385   uint16_t* data = result->GetChars();
386   for (int i = 0; i < non_ascii_start; i++) {
387     *data++ = *ascii_data++;
388   }
389   // Now write the remainder.
390   decoder->WriteUtf16(data, utf16_length);
391   return result;
392 }
393 
NewStringFromTwoByte(const uc16 * string,int length,PretenureFlag pretenure)394 MaybeHandle<String> Factory::NewStringFromTwoByte(const uc16* string,
395                                                   int length,
396                                                   PretenureFlag pretenure) {
397   if (length == 0) return empty_string();
398   if (String::IsOneByte(string, length)) {
399     if (length == 1) return LookupSingleCharacterStringFromCode(string[0]);
400     Handle<SeqOneByteString> result;
401     ASSIGN_RETURN_ON_EXCEPTION(
402         isolate(),
403         result,
404         NewRawOneByteString(length, pretenure),
405         String);
406     CopyChars(result->GetChars(), string, length);
407     return result;
408   } else {
409     Handle<SeqTwoByteString> result;
410     ASSIGN_RETURN_ON_EXCEPTION(
411         isolate(),
412         result,
413         NewRawTwoByteString(length, pretenure),
414         String);
415     CopyChars(result->GetChars(), string, length);
416     return result;
417   }
418 }
419 
NewStringFromTwoByte(Vector<const uc16> string,PretenureFlag pretenure)420 MaybeHandle<String> Factory::NewStringFromTwoByte(Vector<const uc16> string,
421                                                   PretenureFlag pretenure) {
422   return NewStringFromTwoByte(string.start(), string.length(), pretenure);
423 }
424 
NewStringFromTwoByte(const ZoneVector<uc16> * string,PretenureFlag pretenure)425 MaybeHandle<String> Factory::NewStringFromTwoByte(
426     const ZoneVector<uc16>* string, PretenureFlag pretenure) {
427   return NewStringFromTwoByte(string->data(), static_cast<int>(string->size()),
428                               pretenure);
429 }
430 
NewInternalizedStringFromUtf8(Vector<const char> str,int chars,uint32_t hash_field)431 Handle<String> Factory::NewInternalizedStringFromUtf8(Vector<const char> str,
432                                                       int chars,
433                                                       uint32_t hash_field) {
434   CALL_HEAP_FUNCTION(
435       isolate(),
436       isolate()->heap()->AllocateInternalizedStringFromUtf8(
437           str, chars, hash_field),
438       String);
439 }
440 
441 
NewOneByteInternalizedString(Vector<const uint8_t> str,uint32_t hash_field)442 MUST_USE_RESULT Handle<String> Factory::NewOneByteInternalizedString(
443       Vector<const uint8_t> str,
444       uint32_t hash_field) {
445   CALL_HEAP_FUNCTION(
446       isolate(),
447       isolate()->heap()->AllocateOneByteInternalizedString(str, hash_field),
448       String);
449 }
450 
451 
NewOneByteInternalizedSubString(Handle<SeqOneByteString> string,int offset,int length,uint32_t hash_field)452 MUST_USE_RESULT Handle<String> Factory::NewOneByteInternalizedSubString(
453     Handle<SeqOneByteString> string, int offset, int length,
454     uint32_t hash_field) {
455   CALL_HEAP_FUNCTION(
456       isolate(), isolate()->heap()->AllocateOneByteInternalizedString(
457                      Vector<const uint8_t>(string->GetChars() + offset, length),
458                      hash_field),
459       String);
460 }
461 
462 
NewTwoByteInternalizedString(Vector<const uc16> str,uint32_t hash_field)463 MUST_USE_RESULT Handle<String> Factory::NewTwoByteInternalizedString(
464       Vector<const uc16> str,
465       uint32_t hash_field) {
466   CALL_HEAP_FUNCTION(
467       isolate(),
468       isolate()->heap()->AllocateTwoByteInternalizedString(str, hash_field),
469       String);
470 }
471 
472 
NewInternalizedStringImpl(Handle<String> string,int chars,uint32_t hash_field)473 Handle<String> Factory::NewInternalizedStringImpl(
474     Handle<String> string, int chars, uint32_t hash_field) {
475   CALL_HEAP_FUNCTION(
476       isolate(),
477       isolate()->heap()->AllocateInternalizedStringImpl(
478           *string, chars, hash_field),
479       String);
480 }
481 
482 namespace {
483 
GetInternalizedStringMap(Factory * f,Handle<String> string)484 MaybeHandle<Map> GetInternalizedStringMap(Factory* f, Handle<String> string) {
485   switch (string->map()->instance_type()) {
486     case STRING_TYPE:
487       return f->internalized_string_map();
488     case ONE_BYTE_STRING_TYPE:
489       return f->one_byte_internalized_string_map();
490     case EXTERNAL_STRING_TYPE:
491       return f->external_internalized_string_map();
492     case EXTERNAL_ONE_BYTE_STRING_TYPE:
493       return f->external_one_byte_internalized_string_map();
494     case EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE:
495       return f->external_internalized_string_with_one_byte_data_map();
496     case SHORT_EXTERNAL_STRING_TYPE:
497       return f->short_external_internalized_string_map();
498     case SHORT_EXTERNAL_ONE_BYTE_STRING_TYPE:
499       return f->short_external_one_byte_internalized_string_map();
500     case SHORT_EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE:
501       return f->short_external_internalized_string_with_one_byte_data_map();
502     default: return MaybeHandle<Map>();  // No match found.
503   }
504 }
505 
506 }  // namespace
507 
InternalizedStringMapForString(Handle<String> string)508 MaybeHandle<Map> Factory::InternalizedStringMapForString(
509     Handle<String> string) {
510   // If the string is in new space it cannot be used as internalized.
511   if (isolate()->heap()->InNewSpace(*string)) return MaybeHandle<Map>();
512 
513   return GetInternalizedStringMap(this, string);
514 }
515 
516 template <class StringClass>
InternalizeExternalString(Handle<String> string)517 Handle<StringClass> Factory::InternalizeExternalString(Handle<String> string) {
518   Handle<StringClass> cast_string = Handle<StringClass>::cast(string);
519   Handle<Map> map = GetInternalizedStringMap(this, string).ToHandleChecked();
520   Handle<StringClass> external_string = New<StringClass>(map, OLD_SPACE);
521   external_string->set_length(cast_string->length());
522   external_string->set_hash_field(cast_string->hash_field());
523   external_string->set_resource(nullptr);
524   isolate()->heap()->RegisterExternalString(*external_string);
525   return external_string;
526 }
527 
528 template Handle<ExternalOneByteString>
529     Factory::InternalizeExternalString<ExternalOneByteString>(Handle<String>);
530 template Handle<ExternalTwoByteString>
531     Factory::InternalizeExternalString<ExternalTwoByteString>(Handle<String>);
532 
NewRawOneByteString(int length,PretenureFlag pretenure)533 MaybeHandle<SeqOneByteString> Factory::NewRawOneByteString(
534     int length, PretenureFlag pretenure) {
535   if (length > String::kMaxLength || length < 0) {
536     THROW_NEW_ERROR(isolate(), NewInvalidStringLengthError(), SeqOneByteString);
537   }
538   DCHECK(length > 0);  // Use Factory::empty_string() instead.
539   CALL_HEAP_FUNCTION(
540       isolate(),
541       isolate()->heap()->AllocateRawOneByteString(length, pretenure),
542       SeqOneByteString);
543 }
544 
545 
NewRawTwoByteString(int length,PretenureFlag pretenure)546 MaybeHandle<SeqTwoByteString> Factory::NewRawTwoByteString(
547     int length, PretenureFlag pretenure) {
548   if (length > String::kMaxLength || length < 0) {
549     THROW_NEW_ERROR(isolate(), NewInvalidStringLengthError(), SeqTwoByteString);
550   }
551   DCHECK(length > 0);  // Use Factory::empty_string() instead.
552   CALL_HEAP_FUNCTION(
553       isolate(),
554       isolate()->heap()->AllocateRawTwoByteString(length, pretenure),
555       SeqTwoByteString);
556 }
557 
558 
LookupSingleCharacterStringFromCode(uint32_t code)559 Handle<String> Factory::LookupSingleCharacterStringFromCode(uint32_t code) {
560   if (code <= String::kMaxOneByteCharCodeU) {
561     {
562       DisallowHeapAllocation no_allocation;
563       Object* value = single_character_string_cache()->get(code);
564       if (value != *undefined_value()) {
565         return handle(String::cast(value), isolate());
566       }
567     }
568     uint8_t buffer[1];
569     buffer[0] = static_cast<uint8_t>(code);
570     Handle<String> result =
571         InternalizeOneByteString(Vector<const uint8_t>(buffer, 1));
572     single_character_string_cache()->set(code, *result);
573     return result;
574   }
575   DCHECK(code <= String::kMaxUtf16CodeUnitU);
576 
577   Handle<SeqTwoByteString> result = NewRawTwoByteString(1).ToHandleChecked();
578   result->SeqTwoByteStringSet(0, static_cast<uint16_t>(code));
579   return result;
580 }
581 
582 
583 // Returns true for a character in a range.  Both limits are inclusive.
Between(uint32_t character,uint32_t from,uint32_t to)584 static inline bool Between(uint32_t character, uint32_t from, uint32_t to) {
585   // This makes uses of the the unsigned wraparound.
586   return character - from <= to - from;
587 }
588 
589 
MakeOrFindTwoCharacterString(Isolate * isolate,uint16_t c1,uint16_t c2)590 static inline Handle<String> MakeOrFindTwoCharacterString(Isolate* isolate,
591                                                           uint16_t c1,
592                                                           uint16_t c2) {
593   // Numeric strings have a different hash algorithm not known by
594   // LookupTwoCharsStringIfExists, so we skip this step for such strings.
595   if (!Between(c1, '0', '9') || !Between(c2, '0', '9')) {
596     Handle<String> result;
597     if (StringTable::LookupTwoCharsStringIfExists(isolate, c1, c2).
598         ToHandle(&result)) {
599       return result;
600     }
601   }
602 
603   // Now we know the length is 2, we might as well make use of that fact
604   // when building the new string.
605   if (static_cast<unsigned>(c1 | c2) <= String::kMaxOneByteCharCodeU) {
606     // We can do this.
607     DCHECK(base::bits::IsPowerOfTwo32(String::kMaxOneByteCharCodeU +
608                                       1));  // because of this.
609     Handle<SeqOneByteString> str =
610         isolate->factory()->NewRawOneByteString(2).ToHandleChecked();
611     uint8_t* dest = str->GetChars();
612     dest[0] = static_cast<uint8_t>(c1);
613     dest[1] = static_cast<uint8_t>(c2);
614     return str;
615   } else {
616     Handle<SeqTwoByteString> str =
617         isolate->factory()->NewRawTwoByteString(2).ToHandleChecked();
618     uc16* dest = str->GetChars();
619     dest[0] = c1;
620     dest[1] = c2;
621     return str;
622   }
623 }
624 
625 
626 template<typename SinkChar, typename StringType>
ConcatStringContent(Handle<StringType> result,Handle<String> first,Handle<String> second)627 Handle<String> ConcatStringContent(Handle<StringType> result,
628                                    Handle<String> first,
629                                    Handle<String> second) {
630   DisallowHeapAllocation pointer_stays_valid;
631   SinkChar* sink = result->GetChars();
632   String::WriteToFlat(*first, sink, 0, first->length());
633   String::WriteToFlat(*second, sink + first->length(), 0, second->length());
634   return result;
635 }
636 
637 
NewConsString(Handle<String> left,Handle<String> right)638 MaybeHandle<String> Factory::NewConsString(Handle<String> left,
639                                            Handle<String> right) {
640   if (left->IsThinString()) {
641     left = handle(Handle<ThinString>::cast(left)->actual(), isolate());
642   }
643   if (right->IsThinString()) {
644     right = handle(Handle<ThinString>::cast(right)->actual(), isolate());
645   }
646   int left_length = left->length();
647   if (left_length == 0) return right;
648   int right_length = right->length();
649   if (right_length == 0) return left;
650 
651   int length = left_length + right_length;
652 
653   if (length == 2) {
654     uint16_t c1 = left->Get(0);
655     uint16_t c2 = right->Get(0);
656     return MakeOrFindTwoCharacterString(isolate(), c1, c2);
657   }
658 
659   // Make sure that an out of memory exception is thrown if the length
660   // of the new cons string is too large.
661   if (length > String::kMaxLength || length < 0) {
662     THROW_NEW_ERROR(isolate(), NewInvalidStringLengthError(), String);
663   }
664 
665   bool left_is_one_byte = left->IsOneByteRepresentation();
666   bool right_is_one_byte = right->IsOneByteRepresentation();
667   bool is_one_byte = left_is_one_byte && right_is_one_byte;
668   bool is_one_byte_data_in_two_byte_string = false;
669   if (!is_one_byte) {
670     // At least one of the strings uses two-byte representation so we
671     // can't use the fast case code for short one-byte strings below, but
672     // we can try to save memory if all chars actually fit in one-byte.
673     is_one_byte_data_in_two_byte_string =
674         left->HasOnlyOneByteChars() && right->HasOnlyOneByteChars();
675     if (is_one_byte_data_in_two_byte_string) {
676       isolate()->counters()->string_add_runtime_ext_to_one_byte()->Increment();
677     }
678   }
679 
680   // If the resulting string is small make a flat string.
681   if (length < ConsString::kMinLength) {
682     // Note that neither of the two inputs can be a slice because:
683     STATIC_ASSERT(ConsString::kMinLength <= SlicedString::kMinLength);
684     DCHECK(left->IsFlat());
685     DCHECK(right->IsFlat());
686 
687     STATIC_ASSERT(ConsString::kMinLength <= String::kMaxLength);
688     if (is_one_byte) {
689       Handle<SeqOneByteString> result =
690           NewRawOneByteString(length).ToHandleChecked();
691       DisallowHeapAllocation no_gc;
692       uint8_t* dest = result->GetChars();
693       // Copy left part.
694       const uint8_t* src =
695           left->IsExternalString()
696               ? Handle<ExternalOneByteString>::cast(left)->GetChars()
697               : Handle<SeqOneByteString>::cast(left)->GetChars();
698       for (int i = 0; i < left_length; i++) *dest++ = src[i];
699       // Copy right part.
700       src = right->IsExternalString()
701                 ? Handle<ExternalOneByteString>::cast(right)->GetChars()
702                 : Handle<SeqOneByteString>::cast(right)->GetChars();
703       for (int i = 0; i < right_length; i++) *dest++ = src[i];
704       return result;
705     }
706 
707     return (is_one_byte_data_in_two_byte_string)
708         ? ConcatStringContent<uint8_t>(
709             NewRawOneByteString(length).ToHandleChecked(), left, right)
710         : ConcatStringContent<uc16>(
711             NewRawTwoByteString(length).ToHandleChecked(), left, right);
712   }
713 
714   Handle<ConsString> result =
715       (is_one_byte || is_one_byte_data_in_two_byte_string)
716           ? New<ConsString>(cons_one_byte_string_map(), NEW_SPACE)
717           : New<ConsString>(cons_string_map(), NEW_SPACE);
718 
719   DisallowHeapAllocation no_gc;
720   WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc);
721 
722   result->set_hash_field(String::kEmptyHashField);
723   result->set_length(length);
724   result->set_first(*left, mode);
725   result->set_second(*right, mode);
726   return result;
727 }
728 
NewSurrogatePairString(uint16_t lead,uint16_t trail)729 Handle<String> Factory::NewSurrogatePairString(uint16_t lead, uint16_t trail) {
730   DCHECK_GE(lead, 0xD800);
731   DCHECK_LE(lead, 0xDBFF);
732   DCHECK_GE(trail, 0xDC00);
733   DCHECK_LE(trail, 0xDFFF);
734 
735   Handle<SeqTwoByteString> str =
736       isolate()->factory()->NewRawTwoByteString(2).ToHandleChecked();
737   uc16* dest = str->GetChars();
738   dest[0] = lead;
739   dest[1] = trail;
740   return str;
741 }
742 
NewProperSubString(Handle<String> str,int begin,int end)743 Handle<String> Factory::NewProperSubString(Handle<String> str,
744                                            int begin,
745                                            int end) {
746 #if VERIFY_HEAP
747   if (FLAG_verify_heap) str->StringVerify();
748 #endif
749   DCHECK(begin > 0 || end < str->length());
750 
751   str = String::Flatten(str);
752 
753   int length = end - begin;
754   if (length <= 0) return empty_string();
755   if (length == 1) {
756     return LookupSingleCharacterStringFromCode(str->Get(begin));
757   }
758   if (length == 2) {
759     // Optimization for 2-byte strings often used as keys in a decompression
760     // dictionary.  Check whether we already have the string in the string
761     // table to prevent creation of many unnecessary strings.
762     uint16_t c1 = str->Get(begin);
763     uint16_t c2 = str->Get(begin + 1);
764     return MakeOrFindTwoCharacterString(isolate(), c1, c2);
765   }
766 
767   if (!FLAG_string_slices || length < SlicedString::kMinLength) {
768     if (str->IsOneByteRepresentation()) {
769       Handle<SeqOneByteString> result =
770           NewRawOneByteString(length).ToHandleChecked();
771       uint8_t* dest = result->GetChars();
772       DisallowHeapAllocation no_gc;
773       String::WriteToFlat(*str, dest, begin, end);
774       return result;
775     } else {
776       Handle<SeqTwoByteString> result =
777           NewRawTwoByteString(length).ToHandleChecked();
778       uc16* dest = result->GetChars();
779       DisallowHeapAllocation no_gc;
780       String::WriteToFlat(*str, dest, begin, end);
781       return result;
782     }
783   }
784 
785   int offset = begin;
786 
787   if (str->IsSlicedString()) {
788     Handle<SlicedString> slice = Handle<SlicedString>::cast(str);
789     str = Handle<String>(slice->parent(), isolate());
790     offset += slice->offset();
791   }
792   if (str->IsThinString()) {
793     Handle<ThinString> thin = Handle<ThinString>::cast(str);
794     str = handle(thin->actual(), isolate());
795   }
796 
797   DCHECK(str->IsSeqString() || str->IsExternalString());
798   Handle<Map> map = str->IsOneByteRepresentation()
799                         ? sliced_one_byte_string_map()
800                         : sliced_string_map();
801   Handle<SlicedString> slice = New<SlicedString>(map, NEW_SPACE);
802 
803   slice->set_hash_field(String::kEmptyHashField);
804   slice->set_length(length);
805   slice->set_parent(*str);
806   slice->set_offset(offset);
807   return slice;
808 }
809 
810 
NewExternalStringFromOneByte(const ExternalOneByteString::Resource * resource)811 MaybeHandle<String> Factory::NewExternalStringFromOneByte(
812     const ExternalOneByteString::Resource* resource) {
813   size_t length = resource->length();
814   if (length > static_cast<size_t>(String::kMaxLength)) {
815     THROW_NEW_ERROR(isolate(), NewInvalidStringLengthError(), String);
816   }
817   if (length == 0) return empty_string();
818 
819   Handle<Map> map;
820   if (resource->IsCompressible()) {
821     // TODO(hajimehoshi): Rename this to 'uncached_external_one_byte_string_map'
822     map = short_external_one_byte_string_map();
823   } else {
824     map = external_one_byte_string_map();
825   }
826   Handle<ExternalOneByteString> external_string =
827       New<ExternalOneByteString>(map, NEW_SPACE);
828   external_string->set_length(static_cast<int>(length));
829   external_string->set_hash_field(String::kEmptyHashField);
830   external_string->set_resource(resource);
831 
832   return external_string;
833 }
834 
835 
NewExternalStringFromTwoByte(const ExternalTwoByteString::Resource * resource)836 MaybeHandle<String> Factory::NewExternalStringFromTwoByte(
837     const ExternalTwoByteString::Resource* resource) {
838   size_t length = resource->length();
839   if (length > static_cast<size_t>(String::kMaxLength)) {
840     THROW_NEW_ERROR(isolate(), NewInvalidStringLengthError(), String);
841   }
842   if (length == 0) return empty_string();
843 
844   // For small strings we check whether the resource contains only
845   // one byte characters.  If yes, we use a different string map.
846   static const size_t kOneByteCheckLengthLimit = 32;
847   bool is_one_byte = length <= kOneByteCheckLengthLimit &&
848       String::IsOneByte(resource->data(), static_cast<int>(length));
849   Handle<Map> map;
850   if (resource->IsCompressible()) {
851     // TODO(hajimehoshi): Rename these to 'uncached_external_string_...'.
852     map = is_one_byte ? short_external_string_with_one_byte_data_map()
853                       : short_external_string_map();
854   } else {
855     map = is_one_byte ? external_string_with_one_byte_data_map()
856                       : external_string_map();
857   }
858   Handle<ExternalTwoByteString> external_string =
859       New<ExternalTwoByteString>(map, NEW_SPACE);
860   external_string->set_length(static_cast<int>(length));
861   external_string->set_hash_field(String::kEmptyHashField);
862   external_string->set_resource(resource);
863 
864   return external_string;
865 }
866 
NewNativeSourceString(const ExternalOneByteString::Resource * resource)867 Handle<ExternalOneByteString> Factory::NewNativeSourceString(
868     const ExternalOneByteString::Resource* resource) {
869   size_t length = resource->length();
870   DCHECK_LE(length, static_cast<size_t>(String::kMaxLength));
871 
872   Handle<Map> map = native_source_string_map();
873   Handle<ExternalOneByteString> external_string =
874       New<ExternalOneByteString>(map, OLD_SPACE);
875   external_string->set_length(static_cast<int>(length));
876   external_string->set_hash_field(String::kEmptyHashField);
877   external_string->set_resource(resource);
878 
879   return external_string;
880 }
881 
NewJSStringIterator(Handle<String> string)882 Handle<JSStringIterator> Factory::NewJSStringIterator(Handle<String> string) {
883   Handle<Map> map(isolate()->native_context()->string_iterator_map(),
884                   isolate());
885   Handle<String> flat_string = String::Flatten(string);
886   Handle<JSStringIterator> iterator =
887       Handle<JSStringIterator>::cast(NewJSObjectFromMap(map));
888   iterator->set_string(*flat_string);
889   iterator->set_index(0);
890 
891   return iterator;
892 }
893 
NewSymbol()894 Handle<Symbol> Factory::NewSymbol() {
895   CALL_HEAP_FUNCTION(
896       isolate(),
897       isolate()->heap()->AllocateSymbol(),
898       Symbol);
899 }
900 
901 
NewPrivateSymbol()902 Handle<Symbol> Factory::NewPrivateSymbol() {
903   Handle<Symbol> symbol = NewSymbol();
904   symbol->set_is_private(true);
905   return symbol;
906 }
907 
908 
NewNativeContext()909 Handle<Context> Factory::NewNativeContext() {
910   Handle<FixedArray> array =
911       NewFixedArray(Context::NATIVE_CONTEXT_SLOTS, TENURED);
912   array->set_map_no_write_barrier(*native_context_map());
913   Handle<Context> context = Handle<Context>::cast(array);
914   context->set_native_context(*context);
915   context->set_errors_thrown(Smi::kZero);
916   context->set_math_random_index(Smi::kZero);
917   Handle<WeakCell> weak_cell = NewWeakCell(context);
918   context->set_self_weak_cell(*weak_cell);
919   DCHECK(context->IsNativeContext());
920   return context;
921 }
922 
923 
NewScriptContext(Handle<JSFunction> function,Handle<ScopeInfo> scope_info)924 Handle<Context> Factory::NewScriptContext(Handle<JSFunction> function,
925                                           Handle<ScopeInfo> scope_info) {
926   DCHECK_EQ(scope_info->scope_type(), SCRIPT_SCOPE);
927   Handle<FixedArray> array =
928       NewFixedArray(scope_info->ContextLength(), TENURED);
929   array->set_map_no_write_barrier(*script_context_map());
930   Handle<Context> context = Handle<Context>::cast(array);
931   context->set_closure(*function);
932   context->set_previous(function->context());
933   context->set_extension(*scope_info);
934   context->set_native_context(function->native_context());
935   DCHECK(context->IsScriptContext());
936   return context;
937 }
938 
939 
NewScriptContextTable()940 Handle<ScriptContextTable> Factory::NewScriptContextTable() {
941   Handle<FixedArray> array = NewFixedArray(1);
942   array->set_map_no_write_barrier(*script_context_table_map());
943   Handle<ScriptContextTable> context_table =
944       Handle<ScriptContextTable>::cast(array);
945   context_table->set_used(0);
946   return context_table;
947 }
948 
NewModuleContext(Handle<Module> module,Handle<JSFunction> function,Handle<ScopeInfo> scope_info)949 Handle<Context> Factory::NewModuleContext(Handle<Module> module,
950                                           Handle<JSFunction> function,
951                                           Handle<ScopeInfo> scope_info) {
952   DCHECK_EQ(scope_info->scope_type(), MODULE_SCOPE);
953   Handle<FixedArray> array =
954       NewFixedArray(scope_info->ContextLength(), TENURED);
955   array->set_map_no_write_barrier(*module_context_map());
956   Handle<Context> context = Handle<Context>::cast(array);
957   context->set_closure(*function);
958   context->set_previous(function->context());
959   context->set_extension(*module);
960   context->set_native_context(function->native_context());
961   DCHECK(context->IsModuleContext());
962   return context;
963 }
964 
NewFunctionContext(int length,Handle<JSFunction> function,ScopeType scope_type)965 Handle<Context> Factory::NewFunctionContext(int length,
966                                             Handle<JSFunction> function,
967                                             ScopeType scope_type) {
968   DCHECK(function->shared()->scope_info()->scope_type() == scope_type);
969   DCHECK(length >= Context::MIN_CONTEXT_SLOTS);
970   Handle<FixedArray> array = NewFixedArray(length);
971   Handle<Map> map;
972   switch (scope_type) {
973     case EVAL_SCOPE:
974       map = eval_context_map();
975       break;
976     case FUNCTION_SCOPE:
977       map = function_context_map();
978       break;
979     default:
980       UNREACHABLE();
981   }
982   array->set_map_no_write_barrier(*map);
983   Handle<Context> context = Handle<Context>::cast(array);
984   context->set_closure(*function);
985   context->set_previous(function->context());
986   context->set_extension(*the_hole_value());
987   context->set_native_context(function->native_context());
988   return context;
989 }
990 
NewCatchContext(Handle<JSFunction> function,Handle<Context> previous,Handle<ScopeInfo> scope_info,Handle<String> name,Handle<Object> thrown_object)991 Handle<Context> Factory::NewCatchContext(Handle<JSFunction> function,
992                                          Handle<Context> previous,
993                                          Handle<ScopeInfo> scope_info,
994                                          Handle<String> name,
995                                          Handle<Object> thrown_object) {
996   STATIC_ASSERT(Context::MIN_CONTEXT_SLOTS == Context::THROWN_OBJECT_INDEX);
997   Handle<ContextExtension> extension = NewContextExtension(scope_info, name);
998   Handle<FixedArray> array = NewFixedArray(Context::MIN_CONTEXT_SLOTS + 1);
999   array->set_map_no_write_barrier(*catch_context_map());
1000   Handle<Context> context = Handle<Context>::cast(array);
1001   context->set_closure(*function);
1002   context->set_previous(*previous);
1003   context->set_extension(*extension);
1004   context->set_native_context(previous->native_context());
1005   context->set(Context::THROWN_OBJECT_INDEX, *thrown_object);
1006   return context;
1007 }
1008 
NewDebugEvaluateContext(Handle<Context> previous,Handle<ScopeInfo> scope_info,Handle<JSReceiver> extension,Handle<Context> wrapped,Handle<StringSet> whitelist)1009 Handle<Context> Factory::NewDebugEvaluateContext(Handle<Context> previous,
1010                                                  Handle<ScopeInfo> scope_info,
1011                                                  Handle<JSReceiver> extension,
1012                                                  Handle<Context> wrapped,
1013                                                  Handle<StringSet> whitelist) {
1014   STATIC_ASSERT(Context::WHITE_LIST_INDEX == Context::MIN_CONTEXT_SLOTS + 1);
1015   DCHECK(scope_info->IsDebugEvaluateScope());
1016   Handle<ContextExtension> context_extension = NewContextExtension(
1017       scope_info, extension.is_null() ? Handle<Object>::cast(undefined_value())
1018                                       : Handle<Object>::cast(extension));
1019   Handle<FixedArray> array = NewFixedArray(Context::MIN_CONTEXT_SLOTS + 2);
1020   array->set_map_no_write_barrier(*debug_evaluate_context_map());
1021   Handle<Context> c = Handle<Context>::cast(array);
1022   c->set_closure(wrapped.is_null() ? previous->closure() : wrapped->closure());
1023   c->set_previous(*previous);
1024   c->set_native_context(previous->native_context());
1025   c->set_extension(*context_extension);
1026   if (!wrapped.is_null()) c->set(Context::WRAPPED_CONTEXT_INDEX, *wrapped);
1027   if (!whitelist.is_null()) c->set(Context::WHITE_LIST_INDEX, *whitelist);
1028   return c;
1029 }
1030 
NewWithContext(Handle<JSFunction> function,Handle<Context> previous,Handle<ScopeInfo> scope_info,Handle<JSReceiver> extension)1031 Handle<Context> Factory::NewWithContext(Handle<JSFunction> function,
1032                                         Handle<Context> previous,
1033                                         Handle<ScopeInfo> scope_info,
1034                                         Handle<JSReceiver> extension) {
1035   Handle<ContextExtension> context_extension =
1036       NewContextExtension(scope_info, extension);
1037   Handle<FixedArray> array = NewFixedArray(Context::MIN_CONTEXT_SLOTS);
1038   array->set_map_no_write_barrier(*with_context_map());
1039   Handle<Context> context = Handle<Context>::cast(array);
1040   context->set_closure(*function);
1041   context->set_previous(*previous);
1042   context->set_extension(*context_extension);
1043   context->set_native_context(previous->native_context());
1044   return context;
1045 }
1046 
1047 
NewBlockContext(Handle<JSFunction> function,Handle<Context> previous,Handle<ScopeInfo> scope_info)1048 Handle<Context> Factory::NewBlockContext(Handle<JSFunction> function,
1049                                          Handle<Context> previous,
1050                                          Handle<ScopeInfo> scope_info) {
1051   DCHECK_EQ(scope_info->scope_type(), BLOCK_SCOPE);
1052   Handle<FixedArray> array = NewFixedArray(scope_info->ContextLength());
1053   array->set_map_no_write_barrier(*block_context_map());
1054   Handle<Context> context = Handle<Context>::cast(array);
1055   context->set_closure(*function);
1056   context->set_previous(*previous);
1057   context->set_extension(*scope_info);
1058   context->set_native_context(previous->native_context());
1059   return context;
1060 }
1061 
NewStruct(InstanceType type)1062 Handle<Struct> Factory::NewStruct(InstanceType type) {
1063   CALL_HEAP_FUNCTION(
1064       isolate(),
1065       isolate()->heap()->AllocateStruct(type),
1066       Struct);
1067 }
1068 
NewAliasedArgumentsEntry(int aliased_context_slot)1069 Handle<AliasedArgumentsEntry> Factory::NewAliasedArgumentsEntry(
1070     int aliased_context_slot) {
1071   Handle<AliasedArgumentsEntry> entry = Handle<AliasedArgumentsEntry>::cast(
1072       NewStruct(ALIASED_ARGUMENTS_ENTRY_TYPE));
1073   entry->set_aliased_context_slot(aliased_context_slot);
1074   return entry;
1075 }
1076 
1077 
NewAccessorInfo()1078 Handle<AccessorInfo> Factory::NewAccessorInfo() {
1079   Handle<AccessorInfo> info =
1080       Handle<AccessorInfo>::cast(NewStruct(ACCESSOR_INFO_TYPE));
1081   info->set_flag(0);  // Must clear the flag, it was initialized as undefined.
1082   info->set_is_sloppy(true);
1083   return info;
1084 }
1085 
1086 
NewScript(Handle<String> source)1087 Handle<Script> Factory::NewScript(Handle<String> source) {
1088   // Create and initialize script object.
1089   Heap* heap = isolate()->heap();
1090   Handle<Script> script = Handle<Script>::cast(NewStruct(SCRIPT_TYPE));
1091   script->set_source(*source);
1092   script->set_name(heap->undefined_value());
1093   script->set_id(isolate()->heap()->NextScriptId());
1094   script->set_line_offset(0);
1095   script->set_column_offset(0);
1096   script->set_context_data(heap->undefined_value());
1097   script->set_type(Script::TYPE_NORMAL);
1098   script->set_wrapper(heap->undefined_value());
1099   script->set_line_ends(heap->undefined_value());
1100   script->set_eval_from_shared(heap->undefined_value());
1101   script->set_eval_from_position(0);
1102   script->set_shared_function_infos(*empty_fixed_array(), SKIP_WRITE_BARRIER);
1103   script->set_flags(0);
1104 
1105   heap->set_script_list(*WeakFixedArray::Add(script_list(), script));
1106   return script;
1107 }
1108 
1109 
NewForeign(Address addr,PretenureFlag pretenure)1110 Handle<Foreign> Factory::NewForeign(Address addr, PretenureFlag pretenure) {
1111   CALL_HEAP_FUNCTION(isolate(),
1112                      isolate()->heap()->AllocateForeign(addr, pretenure),
1113                      Foreign);
1114 }
1115 
1116 
NewForeign(const AccessorDescriptor * desc)1117 Handle<Foreign> Factory::NewForeign(const AccessorDescriptor* desc) {
1118   return NewForeign((Address) desc, TENURED);
1119 }
1120 
1121 
NewByteArray(int length,PretenureFlag pretenure)1122 Handle<ByteArray> Factory::NewByteArray(int length, PretenureFlag pretenure) {
1123   DCHECK(0 <= length);
1124   CALL_HEAP_FUNCTION(
1125       isolate(),
1126       isolate()->heap()->AllocateByteArray(length, pretenure),
1127       ByteArray);
1128 }
1129 
1130 
NewBytecodeArray(int length,const byte * raw_bytecodes,int frame_size,int parameter_count,Handle<FixedArray> constant_pool)1131 Handle<BytecodeArray> Factory::NewBytecodeArray(
1132     int length, const byte* raw_bytecodes, int frame_size, int parameter_count,
1133     Handle<FixedArray> constant_pool) {
1134   DCHECK(0 <= length);
1135   CALL_HEAP_FUNCTION(isolate(), isolate()->heap()->AllocateBytecodeArray(
1136                                     length, raw_bytecodes, frame_size,
1137                                     parameter_count, *constant_pool),
1138                      BytecodeArray);
1139 }
1140 
1141 
NewFixedTypedArrayWithExternalPointer(int length,ExternalArrayType array_type,void * external_pointer,PretenureFlag pretenure)1142 Handle<FixedTypedArrayBase> Factory::NewFixedTypedArrayWithExternalPointer(
1143     int length, ExternalArrayType array_type, void* external_pointer,
1144     PretenureFlag pretenure) {
1145   DCHECK(0 <= length && length <= Smi::kMaxValue);
1146   CALL_HEAP_FUNCTION(
1147       isolate(), isolate()->heap()->AllocateFixedTypedArrayWithExternalPointer(
1148                      length, array_type, external_pointer, pretenure),
1149       FixedTypedArrayBase);
1150 }
1151 
1152 
NewFixedTypedArray(int length,ExternalArrayType array_type,bool initialize,PretenureFlag pretenure)1153 Handle<FixedTypedArrayBase> Factory::NewFixedTypedArray(
1154     int length, ExternalArrayType array_type, bool initialize,
1155     PretenureFlag pretenure) {
1156   DCHECK(0 <= length && length <= Smi::kMaxValue);
1157   CALL_HEAP_FUNCTION(isolate(), isolate()->heap()->AllocateFixedTypedArray(
1158                                     length, array_type, initialize, pretenure),
1159                      FixedTypedArrayBase);
1160 }
1161 
NewCell(Handle<Object> value)1162 Handle<Cell> Factory::NewCell(Handle<Object> value) {
1163   AllowDeferredHandleDereference convert_to_cell;
1164   CALL_HEAP_FUNCTION(
1165       isolate(),
1166       isolate()->heap()->AllocateCell(*value),
1167       Cell);
1168 }
1169 
NewNoClosuresCell(Handle<Object> value)1170 Handle<Cell> Factory::NewNoClosuresCell(Handle<Object> value) {
1171   Handle<Cell> cell = NewCell(value);
1172   cell->set_map_no_write_barrier(*no_closures_cell_map());
1173   return cell;
1174 }
1175 
NewOneClosureCell(Handle<Object> value)1176 Handle<Cell> Factory::NewOneClosureCell(Handle<Object> value) {
1177   Handle<Cell> cell = NewCell(value);
1178   cell->set_map_no_write_barrier(*one_closure_cell_map());
1179   return cell;
1180 }
1181 
NewManyClosuresCell(Handle<Object> value)1182 Handle<Cell> Factory::NewManyClosuresCell(Handle<Object> value) {
1183   Handle<Cell> cell = NewCell(value);
1184   cell->set_map_no_write_barrier(*many_closures_cell_map());
1185   return cell;
1186 }
1187 
NewPropertyCell()1188 Handle<PropertyCell> Factory::NewPropertyCell() {
1189   CALL_HEAP_FUNCTION(
1190       isolate(),
1191       isolate()->heap()->AllocatePropertyCell(),
1192       PropertyCell);
1193 }
1194 
1195 
NewWeakCell(Handle<HeapObject> value)1196 Handle<WeakCell> Factory::NewWeakCell(Handle<HeapObject> value) {
1197   // It is safe to dereference the value because we are embedding it
1198   // in cell and not inspecting its fields.
1199   AllowDeferredHandleDereference convert_to_cell;
1200   CALL_HEAP_FUNCTION(isolate(), isolate()->heap()->AllocateWeakCell(*value),
1201                      WeakCell);
1202 }
1203 
1204 
NewTransitionArray(int capacity)1205 Handle<TransitionArray> Factory::NewTransitionArray(int capacity) {
1206   CALL_HEAP_FUNCTION(isolate(),
1207                      isolate()->heap()->AllocateTransitionArray(capacity),
1208                      TransitionArray);
1209 }
1210 
1211 
NewAllocationSite()1212 Handle<AllocationSite> Factory::NewAllocationSite() {
1213   Handle<Map> map = allocation_site_map();
1214   Handle<AllocationSite> site = New<AllocationSite>(map, OLD_SPACE);
1215   site->Initialize();
1216 
1217   // Link the site
1218   site->set_weak_next(isolate()->heap()->allocation_sites_list());
1219   isolate()->heap()->set_allocation_sites_list(*site);
1220   return site;
1221 }
1222 
1223 
NewMap(InstanceType type,int instance_size,ElementsKind elements_kind)1224 Handle<Map> Factory::NewMap(InstanceType type,
1225                             int instance_size,
1226                             ElementsKind elements_kind) {
1227   CALL_HEAP_FUNCTION(
1228       isolate(),
1229       isolate()->heap()->AllocateMap(type, instance_size, elements_kind),
1230       Map);
1231 }
1232 
1233 
CopyJSObject(Handle<JSObject> object)1234 Handle<JSObject> Factory::CopyJSObject(Handle<JSObject> object) {
1235   CALL_HEAP_FUNCTION(isolate(),
1236                      isolate()->heap()->CopyJSObject(*object, NULL),
1237                      JSObject);
1238 }
1239 
1240 
CopyJSObjectWithAllocationSite(Handle<JSObject> object,Handle<AllocationSite> site)1241 Handle<JSObject> Factory::CopyJSObjectWithAllocationSite(
1242     Handle<JSObject> object,
1243     Handle<AllocationSite> site) {
1244   CALL_HEAP_FUNCTION(isolate(),
1245                      isolate()->heap()->CopyJSObject(
1246                          *object,
1247                          site.is_null() ? NULL : *site),
1248                      JSObject);
1249 }
1250 
1251 
CopyFixedArrayWithMap(Handle<FixedArray> array,Handle<Map> map)1252 Handle<FixedArray> Factory::CopyFixedArrayWithMap(Handle<FixedArray> array,
1253                                                   Handle<Map> map) {
1254   CALL_HEAP_FUNCTION(isolate(),
1255                      isolate()->heap()->CopyFixedArrayWithMap(*array, *map),
1256                      FixedArray);
1257 }
1258 
1259 
CopyFixedArrayAndGrow(Handle<FixedArray> array,int grow_by,PretenureFlag pretenure)1260 Handle<FixedArray> Factory::CopyFixedArrayAndGrow(Handle<FixedArray> array,
1261                                                   int grow_by,
1262                                                   PretenureFlag pretenure) {
1263   CALL_HEAP_FUNCTION(isolate(), isolate()->heap()->CopyFixedArrayAndGrow(
1264                                     *array, grow_by, pretenure),
1265                      FixedArray);
1266 }
1267 
CopyFixedArrayUpTo(Handle<FixedArray> array,int new_len,PretenureFlag pretenure)1268 Handle<FixedArray> Factory::CopyFixedArrayUpTo(Handle<FixedArray> array,
1269                                                int new_len,
1270                                                PretenureFlag pretenure) {
1271   CALL_HEAP_FUNCTION(isolate(), isolate()->heap()->CopyFixedArrayUpTo(
1272                                     *array, new_len, pretenure),
1273                      FixedArray);
1274 }
1275 
CopyFixedArray(Handle<FixedArray> array)1276 Handle<FixedArray> Factory::CopyFixedArray(Handle<FixedArray> array) {
1277   CALL_HEAP_FUNCTION(isolate(),
1278                      isolate()->heap()->CopyFixedArray(*array),
1279                      FixedArray);
1280 }
1281 
1282 
CopyAndTenureFixedCOWArray(Handle<FixedArray> array)1283 Handle<FixedArray> Factory::CopyAndTenureFixedCOWArray(
1284     Handle<FixedArray> array) {
1285   DCHECK(isolate()->heap()->InNewSpace(*array));
1286   CALL_HEAP_FUNCTION(isolate(),
1287                      isolate()->heap()->CopyAndTenureFixedCOWArray(*array),
1288                      FixedArray);
1289 }
1290 
1291 
CopyFixedDoubleArray(Handle<FixedDoubleArray> array)1292 Handle<FixedDoubleArray> Factory::CopyFixedDoubleArray(
1293     Handle<FixedDoubleArray> array) {
1294   CALL_HEAP_FUNCTION(isolate(),
1295                      isolate()->heap()->CopyFixedDoubleArray(*array),
1296                      FixedDoubleArray);
1297 }
1298 
1299 
NewNumber(double value,PretenureFlag pretenure)1300 Handle<Object> Factory::NewNumber(double value,
1301                                   PretenureFlag pretenure) {
1302   // Materialize as a SMI if possible
1303   int32_t int_value;
1304   if (DoubleToSmiInteger(value, &int_value)) {
1305     return handle(Smi::FromInt(int_value), isolate());
1306   }
1307 
1308   // Materialize the value in the heap.
1309   return NewHeapNumber(value, IMMUTABLE, pretenure);
1310 }
1311 
1312 
NewNumberFromInt(int32_t value,PretenureFlag pretenure)1313 Handle<Object> Factory::NewNumberFromInt(int32_t value,
1314                                          PretenureFlag pretenure) {
1315   if (Smi::IsValid(value)) return handle(Smi::FromInt(value), isolate());
1316   // Bypass NewNumber to avoid various redundant checks.
1317   return NewHeapNumber(FastI2D(value), IMMUTABLE, pretenure);
1318 }
1319 
1320 
NewNumberFromUint(uint32_t value,PretenureFlag pretenure)1321 Handle<Object> Factory::NewNumberFromUint(uint32_t value,
1322                                           PretenureFlag pretenure) {
1323   int32_t int32v = static_cast<int32_t>(value);
1324   if (int32v >= 0 && Smi::IsValid(int32v)) {
1325     return handle(Smi::FromInt(int32v), isolate());
1326   }
1327   return NewHeapNumber(FastUI2D(value), IMMUTABLE, pretenure);
1328 }
1329 
NewHeapNumber(MutableMode mode,PretenureFlag pretenure)1330 Handle<HeapNumber> Factory::NewHeapNumber(MutableMode mode,
1331                                           PretenureFlag pretenure) {
1332   CALL_HEAP_FUNCTION(isolate(),
1333                      isolate()->heap()->AllocateHeapNumber(mode, pretenure),
1334                      HeapNumber);
1335 }
1336 
NewError(Handle<JSFunction> constructor,MessageTemplate::Template template_index,Handle<Object> arg0,Handle<Object> arg1,Handle<Object> arg2)1337 Handle<Object> Factory::NewError(Handle<JSFunction> constructor,
1338                                  MessageTemplate::Template template_index,
1339                                  Handle<Object> arg0, Handle<Object> arg1,
1340                                  Handle<Object> arg2) {
1341   HandleScope scope(isolate());
1342   if (isolate()->bootstrapper()->IsActive()) {
1343     // During bootstrapping we cannot construct error objects.
1344     return scope.CloseAndEscape(NewStringFromAsciiChecked(
1345         MessageTemplate::TemplateString(template_index)));
1346   }
1347 
1348   if (arg0.is_null()) arg0 = undefined_value();
1349   if (arg1.is_null()) arg1 = undefined_value();
1350   if (arg2.is_null()) arg2 = undefined_value();
1351 
1352   Handle<Object> result;
1353   if (!ErrorUtils::MakeGenericError(isolate(), constructor, template_index,
1354                                     arg0, arg1, arg2, SKIP_NONE)
1355            .ToHandle(&result)) {
1356     // If an exception is thrown while
1357     // running the factory method, use the exception as the result.
1358     DCHECK(isolate()->has_pending_exception());
1359     result = handle(isolate()->pending_exception(), isolate());
1360     isolate()->clear_pending_exception();
1361   }
1362 
1363   return scope.CloseAndEscape(result);
1364 }
1365 
1366 
NewError(Handle<JSFunction> constructor,Handle<String> message)1367 Handle<Object> Factory::NewError(Handle<JSFunction> constructor,
1368                                  Handle<String> message) {
1369   // Construct a new error object. If an exception is thrown, use the exception
1370   // as the result.
1371 
1372   Handle<Object> no_caller;
1373   MaybeHandle<Object> maybe_error =
1374       ErrorUtils::Construct(isolate(), constructor, constructor, message,
1375                             SKIP_NONE, no_caller, false);
1376   if (maybe_error.is_null()) {
1377     DCHECK(isolate()->has_pending_exception());
1378     maybe_error = handle(isolate()->pending_exception(), isolate());
1379     isolate()->clear_pending_exception();
1380   }
1381 
1382   return maybe_error.ToHandleChecked();
1383 }
1384 
NewInvalidStringLengthError()1385 Handle<Object> Factory::NewInvalidStringLengthError() {
1386   // Invalidate the "string length" protector.
1387   if (isolate()->IsStringLengthOverflowIntact()) {
1388     isolate()->InvalidateStringLengthOverflowProtector();
1389   }
1390   return NewRangeError(MessageTemplate::kInvalidStringLength);
1391 }
1392 
1393 #define DEFINE_ERROR(NAME, name)                                              \
1394   Handle<Object> Factory::New##NAME(MessageTemplate::Template template_index, \
1395                                     Handle<Object> arg0, Handle<Object> arg1, \
1396                                     Handle<Object> arg2) {                    \
1397     return NewError(isolate()->name##_function(), template_index, arg0, arg1, \
1398                     arg2);                                                    \
1399   }
DEFINE_ERROR(Error,error)1400 DEFINE_ERROR(Error, error)
1401 DEFINE_ERROR(EvalError, eval_error)
1402 DEFINE_ERROR(RangeError, range_error)
1403 DEFINE_ERROR(ReferenceError, reference_error)
1404 DEFINE_ERROR(SyntaxError, syntax_error)
1405 DEFINE_ERROR(TypeError, type_error)
1406 DEFINE_ERROR(WasmCompileError, wasm_compile_error)
1407 DEFINE_ERROR(WasmLinkError, wasm_link_error)
1408 DEFINE_ERROR(WasmRuntimeError, wasm_runtime_error)
1409 #undef DEFINE_ERROR
1410 
1411 Handle<JSFunction> Factory::NewFunction(Handle<Map> map,
1412                                         Handle<SharedFunctionInfo> info,
1413                                         Handle<Object> context_or_undefined,
1414                                         PretenureFlag pretenure) {
1415   AllocationSpace space = pretenure == TENURED ? OLD_SPACE : NEW_SPACE;
1416   Handle<JSFunction> function = New<JSFunction>(map, space);
1417   DCHECK(context_or_undefined->IsContext() ||
1418          context_or_undefined->IsUndefined(isolate()));
1419 
1420   function->initialize_properties();
1421   function->initialize_elements();
1422   function->set_shared(*info);
1423   function->set_code(info->code());
1424   function->set_context(*context_or_undefined);
1425   function->set_prototype_or_initial_map(*the_hole_value());
1426   function->set_feedback_vector_cell(*undefined_cell());
1427   function->set_next_function_link(*undefined_value(), SKIP_WRITE_BARRIER);
1428   isolate()->heap()->InitializeJSObjectBody(*function, *map, JSFunction::kSize);
1429   return function;
1430 }
1431 
1432 
NewFunction(Handle<Map> map,Handle<String> name,MaybeHandle<Code> code)1433 Handle<JSFunction> Factory::NewFunction(Handle<Map> map,
1434                                         Handle<String> name,
1435                                         MaybeHandle<Code> code) {
1436   Handle<Context> context(isolate()->native_context());
1437   Handle<SharedFunctionInfo> info =
1438       NewSharedFunctionInfo(name, code, map->is_constructor());
1439   DCHECK(is_sloppy(info->language_mode()));
1440   DCHECK(!map->IsUndefined(isolate()));
1441   DCHECK(
1442       map.is_identical_to(isolate()->sloppy_function_map()) ||
1443       map.is_identical_to(isolate()->sloppy_function_without_prototype_map()) ||
1444       map.is_identical_to(
1445           isolate()->sloppy_function_with_readonly_prototype_map()) ||
1446       map.is_identical_to(isolate()->strict_function_map()) ||
1447       map.is_identical_to(isolate()->strict_function_without_prototype_map()) ||
1448       // TODO(titzer): wasm_function_map() could be undefined here. ugly.
1449       (*map == context->get(Context::WASM_FUNCTION_MAP_INDEX)) ||
1450       (*map == context->get(Context::NATIVE_FUNCTION_MAP_INDEX)) ||
1451       map.is_identical_to(isolate()->proxy_function_map()));
1452   return NewFunction(map, info, context);
1453 }
1454 
1455 
NewFunction(Handle<String> name)1456 Handle<JSFunction> Factory::NewFunction(Handle<String> name) {
1457   return NewFunction(
1458       isolate()->sloppy_function_map(), name, MaybeHandle<Code>());
1459 }
1460 
1461 
NewFunctionWithoutPrototype(Handle<String> name,Handle<Code> code,bool is_strict)1462 Handle<JSFunction> Factory::NewFunctionWithoutPrototype(Handle<String> name,
1463                                                         Handle<Code> code,
1464                                                         bool is_strict) {
1465   Handle<Map> map = is_strict
1466                         ? isolate()->strict_function_without_prototype_map()
1467                         : isolate()->sloppy_function_without_prototype_map();
1468   return NewFunction(map, name, code);
1469 }
1470 
1471 
NewFunction(Handle<String> name,Handle<Code> code,Handle<Object> prototype,bool is_strict)1472 Handle<JSFunction> Factory::NewFunction(Handle<String> name, Handle<Code> code,
1473                                         Handle<Object> prototype,
1474                                         bool is_strict) {
1475   Handle<Map> map = is_strict ? isolate()->strict_function_map()
1476                               : isolate()->sloppy_function_map();
1477   Handle<JSFunction> result = NewFunction(map, name, code);
1478   result->set_prototype_or_initial_map(*prototype);
1479   return result;
1480 }
1481 
1482 
NewFunction(Handle<String> name,Handle<Code> code,Handle<Object> prototype,InstanceType type,int instance_size,bool is_strict)1483 Handle<JSFunction> Factory::NewFunction(Handle<String> name, Handle<Code> code,
1484                                         Handle<Object> prototype,
1485                                         InstanceType type, int instance_size,
1486                                         bool is_strict) {
1487   // Allocate the function
1488   Handle<JSFunction> function = NewFunction(name, code, prototype, is_strict);
1489 
1490   ElementsKind elements_kind =
1491       type == JS_ARRAY_TYPE ? FAST_SMI_ELEMENTS : FAST_HOLEY_SMI_ELEMENTS;
1492   Handle<Map> initial_map = NewMap(type, instance_size, elements_kind);
1493   // TODO(littledan): Why do we have this is_generator test when
1494   // NewFunctionPrototype already handles finding an appropriately
1495   // shared prototype?
1496   if (!IsResumableFunction(function->shared()->kind())) {
1497     if (prototype->IsTheHole(isolate())) {
1498       prototype = NewFunctionPrototype(function);
1499     }
1500   }
1501 
1502   JSFunction::SetInitialMap(function, initial_map,
1503                             Handle<JSReceiver>::cast(prototype));
1504 
1505   return function;
1506 }
1507 
1508 
NewFunction(Handle<String> name,Handle<Code> code,InstanceType type,int instance_size)1509 Handle<JSFunction> Factory::NewFunction(Handle<String> name,
1510                                         Handle<Code> code,
1511                                         InstanceType type,
1512                                         int instance_size) {
1513   return NewFunction(name, code, the_hole_value(), type, instance_size);
1514 }
1515 
1516 
NewFunctionPrototype(Handle<JSFunction> function)1517 Handle<JSObject> Factory::NewFunctionPrototype(Handle<JSFunction> function) {
1518   // Make sure to use globals from the function's context, since the function
1519   // can be from a different context.
1520   Handle<Context> native_context(function->context()->native_context());
1521   Handle<Map> new_map;
1522   if (IsResumableFunction(function->shared()->kind())) {
1523     // Generator and async function prototypes can share maps since they
1524     // don't have "constructor" properties.
1525     new_map = handle(native_context->generator_object_prototype_map());
1526   } else {
1527     // Each function prototype gets a fresh map to avoid unwanted sharing of
1528     // maps between prototypes of different constructors.
1529     Handle<JSFunction> object_function(native_context->object_function());
1530     DCHECK(object_function->has_initial_map());
1531     new_map = handle(object_function->initial_map());
1532   }
1533 
1534   DCHECK(!new_map->is_prototype_map());
1535   Handle<JSObject> prototype = NewJSObjectFromMap(new_map);
1536 
1537   if (!IsResumableFunction(function->shared()->kind())) {
1538     JSObject::AddProperty(prototype, constructor_string(), function, DONT_ENUM);
1539   }
1540 
1541   return prototype;
1542 }
1543 
1544 
NewFunctionFromSharedFunctionInfo(Handle<SharedFunctionInfo> info,Handle<Context> context,PretenureFlag pretenure)1545 Handle<JSFunction> Factory::NewFunctionFromSharedFunctionInfo(
1546     Handle<SharedFunctionInfo> info,
1547     Handle<Context> context,
1548     PretenureFlag pretenure) {
1549   int map_index =
1550       Context::FunctionMapIndex(info->language_mode(), info->kind());
1551   Handle<Map> initial_map(Map::cast(context->native_context()->get(map_index)));
1552 
1553   return NewFunctionFromSharedFunctionInfo(initial_map, info, context,
1554                                            pretenure);
1555 }
1556 
NewFunctionFromSharedFunctionInfo(Handle<SharedFunctionInfo> info,Handle<Context> context,Handle<Cell> vector,PretenureFlag pretenure)1557 Handle<JSFunction> Factory::NewFunctionFromSharedFunctionInfo(
1558     Handle<SharedFunctionInfo> info, Handle<Context> context,
1559     Handle<Cell> vector, PretenureFlag pretenure) {
1560   int map_index =
1561       Context::FunctionMapIndex(info->language_mode(), info->kind());
1562   Handle<Map> initial_map(Map::cast(context->native_context()->get(map_index)));
1563 
1564   return NewFunctionFromSharedFunctionInfo(initial_map, info, context, vector,
1565                                            pretenure);
1566 }
1567 
NewFunctionFromSharedFunctionInfo(Handle<Map> initial_map,Handle<SharedFunctionInfo> info,Handle<Object> context_or_undefined,PretenureFlag pretenure)1568 Handle<JSFunction> Factory::NewFunctionFromSharedFunctionInfo(
1569     Handle<Map> initial_map, Handle<SharedFunctionInfo> info,
1570     Handle<Object> context_or_undefined, PretenureFlag pretenure) {
1571   DCHECK_EQ(JS_FUNCTION_TYPE, initial_map->instance_type());
1572   Handle<JSFunction> result =
1573       NewFunction(initial_map, info, context_or_undefined, pretenure);
1574 
1575   if (info->ic_age() != isolate()->heap()->global_ic_age()) {
1576     info->ResetForNewContext(isolate()->heap()->global_ic_age());
1577   }
1578 
1579   if (context_or_undefined->IsContext()) {
1580     // Give compiler a chance to pre-initialize.
1581     Compiler::PostInstantiation(result, pretenure);
1582   }
1583 
1584   return result;
1585 }
1586 
NewFunctionFromSharedFunctionInfo(Handle<Map> initial_map,Handle<SharedFunctionInfo> info,Handle<Object> context_or_undefined,Handle<Cell> vector,PretenureFlag pretenure)1587 Handle<JSFunction> Factory::NewFunctionFromSharedFunctionInfo(
1588     Handle<Map> initial_map, Handle<SharedFunctionInfo> info,
1589     Handle<Object> context_or_undefined, Handle<Cell> vector,
1590     PretenureFlag pretenure) {
1591   DCHECK_EQ(JS_FUNCTION_TYPE, initial_map->instance_type());
1592   Handle<JSFunction> result =
1593       NewFunction(initial_map, info, context_or_undefined, pretenure);
1594 
1595   // Bump the closure count that is encoded in the vector cell's map.
1596   if (vector->map() == *no_closures_cell_map()) {
1597     vector->set_map(*one_closure_cell_map());
1598   } else if (vector->map() == *one_closure_cell_map()) {
1599     vector->set_map(*many_closures_cell_map());
1600   } else {
1601     DCHECK_EQ(vector->map(), *many_closures_cell_map());
1602   }
1603 
1604   result->set_feedback_vector_cell(*vector);
1605   if (info->ic_age() != isolate()->heap()->global_ic_age()) {
1606     info->ResetForNewContext(isolate()->heap()->global_ic_age());
1607   }
1608 
1609   if (context_or_undefined->IsContext()) {
1610     // Give compiler a chance to pre-initialize.
1611     Compiler::PostInstantiation(result, pretenure);
1612   }
1613 
1614   return result;
1615 }
1616 
NewScopeInfo(int length)1617 Handle<ScopeInfo> Factory::NewScopeInfo(int length) {
1618   Handle<FixedArray> array = NewFixedArray(length, TENURED);
1619   array->set_map_no_write_barrier(*scope_info_map());
1620   Handle<ScopeInfo> scope_info = Handle<ScopeInfo>::cast(array);
1621   return scope_info;
1622 }
1623 
NewModuleInfo()1624 Handle<ModuleInfo> Factory::NewModuleInfo() {
1625   Handle<FixedArray> array = NewFixedArray(ModuleInfo::kLength, TENURED);
1626   array->set_map_no_write_barrier(*module_info_map());
1627   return Handle<ModuleInfo>::cast(array);
1628 }
1629 
NewExternal(void * value)1630 Handle<JSObject> Factory::NewExternal(void* value) {
1631   Handle<Foreign> foreign = NewForeign(static_cast<Address>(value));
1632   Handle<JSObject> external = NewJSObjectFromMap(external_map());
1633   external->SetInternalField(0, *foreign);
1634   return external;
1635 }
1636 
1637 
NewCodeRaw(int object_size,bool immovable)1638 Handle<Code> Factory::NewCodeRaw(int object_size, bool immovable) {
1639   CALL_HEAP_FUNCTION(isolate(),
1640                      isolate()->heap()->AllocateCode(object_size, immovable),
1641                      Code);
1642 }
1643 
1644 
NewCode(const CodeDesc & desc,Code::Flags flags,Handle<Object> self_ref,bool immovable,bool crankshafted,int prologue_offset,bool is_debug)1645 Handle<Code> Factory::NewCode(const CodeDesc& desc,
1646                               Code::Flags flags,
1647                               Handle<Object> self_ref,
1648                               bool immovable,
1649                               bool crankshafted,
1650                               int prologue_offset,
1651                               bool is_debug) {
1652   Handle<ByteArray> reloc_info = NewByteArray(desc.reloc_size, TENURED);
1653 
1654   bool has_unwinding_info = desc.unwinding_info != nullptr;
1655   DCHECK((has_unwinding_info && desc.unwinding_info_size > 0) ||
1656          (!has_unwinding_info && desc.unwinding_info_size == 0));
1657 
1658   // Compute size.
1659   int body_size = desc.instr_size;
1660   int unwinding_info_size_field_size = kInt64Size;
1661   if (has_unwinding_info) {
1662     body_size = RoundUp(body_size, kInt64Size) + desc.unwinding_info_size +
1663                 unwinding_info_size_field_size;
1664   }
1665   int obj_size = Code::SizeFor(RoundUp(body_size, kObjectAlignment));
1666 
1667   Handle<Code> code = NewCodeRaw(obj_size, immovable);
1668   DCHECK(!isolate()->heap()->memory_allocator()->code_range()->valid() ||
1669          isolate()->heap()->memory_allocator()->code_range()->contains(
1670              code->address()) ||
1671          obj_size <= isolate()->heap()->code_space()->AreaSize());
1672 
1673   // The code object has not been fully initialized yet.  We rely on the
1674   // fact that no allocation will happen from this point on.
1675   DisallowHeapAllocation no_gc;
1676   code->set_gc_metadata(Smi::kZero);
1677   code->set_ic_age(isolate()->heap()->global_ic_age());
1678   code->set_instruction_size(desc.instr_size);
1679   code->set_relocation_info(*reloc_info);
1680   code->set_flags(flags);
1681   code->set_has_unwinding_info(has_unwinding_info);
1682   code->set_raw_kind_specific_flags1(0);
1683   code->set_raw_kind_specific_flags2(0);
1684   code->set_is_crankshafted(crankshafted);
1685   code->set_deoptimization_data(*empty_fixed_array(), SKIP_WRITE_BARRIER);
1686   code->set_raw_type_feedback_info(Smi::kZero);
1687   code->set_next_code_link(*undefined_value(), SKIP_WRITE_BARRIER);
1688   code->set_handler_table(*empty_fixed_array(), SKIP_WRITE_BARRIER);
1689   code->set_source_position_table(*empty_byte_array(), SKIP_WRITE_BARRIER);
1690   code->set_prologue_offset(prologue_offset);
1691   code->set_constant_pool_offset(desc.instr_size - desc.constant_pool_size);
1692   code->set_builtin_index(-1);
1693 
1694   if (code->kind() == Code::OPTIMIZED_FUNCTION) {
1695     code->set_marked_for_deoptimization(false);
1696   }
1697 
1698   if (is_debug) {
1699     DCHECK(code->kind() == Code::FUNCTION);
1700     code->set_has_debug_break_slots(true);
1701   }
1702 
1703   // Allow self references to created code object by patching the handle to
1704   // point to the newly allocated Code object.
1705   if (!self_ref.is_null()) *(self_ref.location()) = *code;
1706 
1707   // Migrate generated code.
1708   // The generated code can contain Object** values (typically from handles)
1709   // that are dereferenced during the copy to point directly to the actual heap
1710   // objects. These pointers can include references to the code object itself,
1711   // through the self_reference parameter.
1712   code->CopyFrom(desc);
1713 
1714 #ifdef VERIFY_HEAP
1715   if (FLAG_verify_heap) code->ObjectVerify();
1716 #endif
1717   return code;
1718 }
1719 
1720 
CopyCode(Handle<Code> code)1721 Handle<Code> Factory::CopyCode(Handle<Code> code) {
1722   CALL_HEAP_FUNCTION(isolate(),
1723                      isolate()->heap()->CopyCode(*code),
1724                      Code);
1725 }
1726 
1727 
CopyBytecodeArray(Handle<BytecodeArray> bytecode_array)1728 Handle<BytecodeArray> Factory::CopyBytecodeArray(
1729     Handle<BytecodeArray> bytecode_array) {
1730   CALL_HEAP_FUNCTION(isolate(),
1731                      isolate()->heap()->CopyBytecodeArray(*bytecode_array),
1732                      BytecodeArray);
1733 }
1734 
NewJSObject(Handle<JSFunction> constructor,PretenureFlag pretenure)1735 Handle<JSObject> Factory::NewJSObject(Handle<JSFunction> constructor,
1736                                       PretenureFlag pretenure) {
1737   JSFunction::EnsureHasInitialMap(constructor);
1738   CALL_HEAP_FUNCTION(
1739       isolate(),
1740       isolate()->heap()->AllocateJSObject(*constructor, pretenure), JSObject);
1741 }
1742 
NewJSObjectWithNullProto(PretenureFlag pretenure)1743 Handle<JSObject> Factory::NewJSObjectWithNullProto(PretenureFlag pretenure) {
1744   Handle<JSObject> result =
1745       NewJSObject(isolate()->object_function(), pretenure);
1746   Handle<Map> new_map =
1747       Map::Copy(Handle<Map>(result->map()), "ObjectWithNullProto");
1748   Map::SetPrototype(new_map, null_value());
1749   JSObject::MigrateToMap(result, new_map);
1750   return result;
1751 }
1752 
NewJSGlobalObject(Handle<JSFunction> constructor)1753 Handle<JSGlobalObject> Factory::NewJSGlobalObject(
1754     Handle<JSFunction> constructor) {
1755   DCHECK(constructor->has_initial_map());
1756   Handle<Map> map(constructor->initial_map());
1757   DCHECK(map->is_dictionary_map());
1758 
1759   // Make sure no field properties are described in the initial map.
1760   // This guarantees us that normalizing the properties does not
1761   // require us to change property values to PropertyCells.
1762   DCHECK(map->NextFreePropertyIndex() == 0);
1763 
1764   // Make sure we don't have a ton of pre-allocated slots in the
1765   // global objects. They will be unused once we normalize the object.
1766   DCHECK(map->unused_property_fields() == 0);
1767   DCHECK(map->GetInObjectProperties() == 0);
1768 
1769   // Initial size of the backing store to avoid resize of the storage during
1770   // bootstrapping. The size differs between the JS global object ad the
1771   // builtins object.
1772   int initial_size = 64;
1773 
1774   // Allocate a dictionary object for backing storage.
1775   int at_least_space_for = map->NumberOfOwnDescriptors() * 2 + initial_size;
1776   Handle<GlobalDictionary> dictionary =
1777       GlobalDictionary::New(isolate(), at_least_space_for);
1778 
1779   // The global object might be created from an object template with accessors.
1780   // Fill these accessors into the dictionary.
1781   Handle<DescriptorArray> descs(map->instance_descriptors());
1782   for (int i = 0; i < map->NumberOfOwnDescriptors(); i++) {
1783     PropertyDetails details = descs->GetDetails(i);
1784     // Only accessors are expected.
1785     DCHECK_EQ(kAccessor, details.kind());
1786     PropertyDetails d(kAccessor, details.attributes(), i + 1,
1787                       PropertyCellType::kMutable);
1788     Handle<Name> name(descs->GetKey(i));
1789     Handle<PropertyCell> cell = NewPropertyCell();
1790     cell->set_value(descs->GetValue(i));
1791     // |dictionary| already contains enough space for all properties.
1792     USE(GlobalDictionary::Add(dictionary, name, cell, d));
1793   }
1794 
1795   // Allocate the global object and initialize it with the backing store.
1796   Handle<JSGlobalObject> global = New<JSGlobalObject>(map, OLD_SPACE);
1797   isolate()->heap()->InitializeJSObjectFromMap(*global, *dictionary, *map);
1798 
1799   // Create a new map for the global object.
1800   Handle<Map> new_map = Map::CopyDropDescriptors(map);
1801   new_map->set_dictionary_map(true);
1802 
1803   // Set up the global object as a normalized object.
1804   global->set_map(*new_map);
1805   global->set_properties(*dictionary);
1806 
1807   // Make sure result is a global object with properties in dictionary.
1808   DCHECK(global->IsJSGlobalObject() && !global->HasFastProperties());
1809   return global;
1810 }
1811 
1812 
NewJSObjectFromMap(Handle<Map> map,PretenureFlag pretenure,Handle<AllocationSite> allocation_site)1813 Handle<JSObject> Factory::NewJSObjectFromMap(
1814     Handle<Map> map,
1815     PretenureFlag pretenure,
1816     Handle<AllocationSite> allocation_site) {
1817   CALL_HEAP_FUNCTION(
1818       isolate(),
1819       isolate()->heap()->AllocateJSObjectFromMap(
1820           *map,
1821           pretenure,
1822           allocation_site.is_null() ? NULL : *allocation_site),
1823       JSObject);
1824 }
1825 
1826 
NewJSArray(ElementsKind elements_kind,PretenureFlag pretenure)1827 Handle<JSArray> Factory::NewJSArray(ElementsKind elements_kind,
1828                                     PretenureFlag pretenure) {
1829   Map* map = isolate()->get_initial_js_array_map(elements_kind);
1830   if (map == nullptr) {
1831     Context* native_context = isolate()->context()->native_context();
1832     JSFunction* array_function = native_context->array_function();
1833     map = array_function->initial_map();
1834   }
1835   return Handle<JSArray>::cast(NewJSObjectFromMap(handle(map), pretenure));
1836 }
1837 
NewJSArray(ElementsKind elements_kind,int length,int capacity,ArrayStorageAllocationMode mode,PretenureFlag pretenure)1838 Handle<JSArray> Factory::NewJSArray(ElementsKind elements_kind, int length,
1839                                     int capacity,
1840                                     ArrayStorageAllocationMode mode,
1841                                     PretenureFlag pretenure) {
1842   Handle<JSArray> array = NewJSArray(elements_kind, pretenure);
1843   NewJSArrayStorage(array, length, capacity, mode);
1844   return array;
1845 }
1846 
NewJSArrayWithElements(Handle<FixedArrayBase> elements,ElementsKind elements_kind,int length,PretenureFlag pretenure)1847 Handle<JSArray> Factory::NewJSArrayWithElements(Handle<FixedArrayBase> elements,
1848                                                 ElementsKind elements_kind,
1849                                                 int length,
1850                                                 PretenureFlag pretenure) {
1851   DCHECK(length <= elements->length());
1852   Handle<JSArray> array = NewJSArray(elements_kind, pretenure);
1853 
1854   array->set_elements(*elements);
1855   array->set_length(Smi::FromInt(length));
1856   JSObject::ValidateElements(array);
1857   return array;
1858 }
1859 
1860 
NewJSArrayStorage(Handle<JSArray> array,int length,int capacity,ArrayStorageAllocationMode mode)1861 void Factory::NewJSArrayStorage(Handle<JSArray> array,
1862                                 int length,
1863                                 int capacity,
1864                                 ArrayStorageAllocationMode mode) {
1865   DCHECK(capacity >= length);
1866 
1867   if (capacity == 0) {
1868     array->set_length(Smi::kZero);
1869     array->set_elements(*empty_fixed_array());
1870     return;
1871   }
1872 
1873   HandleScope inner_scope(isolate());
1874   Handle<FixedArrayBase> elms;
1875   ElementsKind elements_kind = array->GetElementsKind();
1876   if (IsFastDoubleElementsKind(elements_kind)) {
1877     if (mode == DONT_INITIALIZE_ARRAY_ELEMENTS) {
1878       elms = NewFixedDoubleArray(capacity);
1879     } else {
1880       DCHECK(mode == INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE);
1881       elms = NewFixedDoubleArrayWithHoles(capacity);
1882     }
1883   } else {
1884     DCHECK(IsFastSmiOrObjectElementsKind(elements_kind));
1885     if (mode == DONT_INITIALIZE_ARRAY_ELEMENTS) {
1886       elms = NewUninitializedFixedArray(capacity);
1887     } else {
1888       DCHECK(mode == INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE);
1889       elms = NewFixedArrayWithHoles(capacity);
1890     }
1891   }
1892 
1893   array->set_elements(*elms);
1894   array->set_length(Smi::FromInt(length));
1895 }
1896 
NewJSModuleNamespace()1897 Handle<JSModuleNamespace> Factory::NewJSModuleNamespace() {
1898   Handle<Map> map = isolate()->js_module_namespace_map();
1899   Handle<JSModuleNamespace> module_namespace(
1900       Handle<JSModuleNamespace>::cast(NewJSObjectFromMap(map)));
1901   FieldIndex index = FieldIndex::ForDescriptor(
1902       *map, JSModuleNamespace::kToStringTagFieldIndex);
1903   module_namespace->FastPropertyAtPut(index,
1904                                       isolate()->heap()->Module_string());
1905   return module_namespace;
1906 }
1907 
NewJSGeneratorObject(Handle<JSFunction> function)1908 Handle<JSGeneratorObject> Factory::NewJSGeneratorObject(
1909     Handle<JSFunction> function) {
1910   DCHECK(IsResumableFunction(function->shared()->kind()));
1911   JSFunction::EnsureHasInitialMap(function);
1912   Handle<Map> map(function->initial_map());
1913   DCHECK_EQ(JS_GENERATOR_OBJECT_TYPE, map->instance_type());
1914   CALL_HEAP_FUNCTION(
1915       isolate(),
1916       isolate()->heap()->AllocateJSObjectFromMap(*map),
1917       JSGeneratorObject);
1918 }
1919 
NewModule(Handle<SharedFunctionInfo> code)1920 Handle<Module> Factory::NewModule(Handle<SharedFunctionInfo> code) {
1921   Handle<ModuleInfo> module_info(code->scope_info()->ModuleDescriptorInfo(),
1922                                  isolate());
1923   Handle<ObjectHashTable> exports =
1924       ObjectHashTable::New(isolate(), module_info->RegularExportCount());
1925   Handle<FixedArray> regular_exports =
1926       NewFixedArray(module_info->RegularExportCount());
1927   Handle<FixedArray> regular_imports =
1928       NewFixedArray(module_info->regular_imports()->length());
1929   int requested_modules_length = module_info->module_requests()->length();
1930   Handle<FixedArray> requested_modules =
1931       requested_modules_length > 0 ? NewFixedArray(requested_modules_length)
1932                                    : empty_fixed_array();
1933 
1934   Handle<Module> module = Handle<Module>::cast(NewStruct(MODULE_TYPE));
1935   module->set_code(*code);
1936   module->set_exports(*exports);
1937   module->set_regular_exports(*regular_exports);
1938   module->set_regular_imports(*regular_imports);
1939   module->set_hash(isolate()->GenerateIdentityHash(Smi::kMaxValue));
1940   module->set_module_namespace(isolate()->heap()->undefined_value());
1941   module->set_requested_modules(*requested_modules);
1942   DCHECK(!module->instantiated());
1943   DCHECK(!module->evaluated());
1944   return module;
1945 }
1946 
NewJSArrayBuffer(SharedFlag shared,PretenureFlag pretenure)1947 Handle<JSArrayBuffer> Factory::NewJSArrayBuffer(SharedFlag shared,
1948                                                 PretenureFlag pretenure) {
1949   Handle<JSFunction> array_buffer_fun(
1950       shared == SharedFlag::kShared
1951           ? isolate()->native_context()->shared_array_buffer_fun()
1952           : isolate()->native_context()->array_buffer_fun());
1953   CALL_HEAP_FUNCTION(isolate(), isolate()->heap()->AllocateJSObject(
1954                                     *array_buffer_fun, pretenure),
1955                      JSArrayBuffer);
1956 }
1957 
1958 
NewJSDataView()1959 Handle<JSDataView> Factory::NewJSDataView() {
1960   Handle<JSFunction> data_view_fun(
1961       isolate()->native_context()->data_view_fun());
1962   CALL_HEAP_FUNCTION(
1963       isolate(),
1964       isolate()->heap()->AllocateJSObject(*data_view_fun),
1965       JSDataView);
1966 }
1967 
NewJSIteratorResult(Handle<Object> value,bool done)1968 Handle<JSIteratorResult> Factory::NewJSIteratorResult(Handle<Object> value,
1969                                                       bool done) {
1970   Handle<Map> map(isolate()->native_context()->iterator_result_map());
1971   Handle<JSIteratorResult> js_iter_result =
1972       Handle<JSIteratorResult>::cast(NewJSObjectFromMap(map));
1973   js_iter_result->set_value(*value);
1974   js_iter_result->set_done(*ToBoolean(done));
1975   return js_iter_result;
1976 }
1977 
NewJSAsyncFromSyncIterator(Handle<JSReceiver> sync_iterator)1978 Handle<JSAsyncFromSyncIterator> Factory::NewJSAsyncFromSyncIterator(
1979     Handle<JSReceiver> sync_iterator) {
1980   Handle<Map> map(isolate()->native_context()->async_from_sync_iterator_map());
1981   Handle<JSAsyncFromSyncIterator> iterator =
1982       Handle<JSAsyncFromSyncIterator>::cast(NewJSObjectFromMap(map));
1983 
1984   iterator->set_sync_iterator(*sync_iterator);
1985   return iterator;
1986 }
1987 
NewJSMap()1988 Handle<JSMap> Factory::NewJSMap() {
1989   Handle<Map> map(isolate()->native_context()->js_map_map());
1990   Handle<JSMap> js_map = Handle<JSMap>::cast(NewJSObjectFromMap(map));
1991   JSMap::Initialize(js_map, isolate());
1992   return js_map;
1993 }
1994 
1995 
NewJSSet()1996 Handle<JSSet> Factory::NewJSSet() {
1997   Handle<Map> map(isolate()->native_context()->js_set_map());
1998   Handle<JSSet> js_set = Handle<JSSet>::cast(NewJSObjectFromMap(map));
1999   JSSet::Initialize(js_set, isolate());
2000   return js_set;
2001 }
2002 
2003 
NewJSMapIterator()2004 Handle<JSMapIterator> Factory::NewJSMapIterator() {
2005   Handle<Map> map(isolate()->native_context()->map_iterator_map());
2006   CALL_HEAP_FUNCTION(isolate(),
2007                      isolate()->heap()->AllocateJSObjectFromMap(*map),
2008                      JSMapIterator);
2009 }
2010 
2011 
NewJSSetIterator()2012 Handle<JSSetIterator> Factory::NewJSSetIterator() {
2013   Handle<Map> map(isolate()->native_context()->set_iterator_map());
2014   CALL_HEAP_FUNCTION(isolate(),
2015                      isolate()->heap()->AllocateJSObjectFromMap(*map),
2016                      JSSetIterator);
2017 }
2018 
2019 
2020 namespace {
2021 
GetExternalArrayElementsKind(ExternalArrayType type)2022 ElementsKind GetExternalArrayElementsKind(ExternalArrayType type) {
2023   switch (type) {
2024 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
2025   case kExternal##Type##Array:                          \
2026     return TYPE##_ELEMENTS;
2027     TYPED_ARRAYS(TYPED_ARRAY_CASE)
2028   }
2029   UNREACHABLE();
2030   return FIRST_FIXED_TYPED_ARRAY_ELEMENTS_KIND;
2031 #undef TYPED_ARRAY_CASE
2032 }
2033 
2034 
GetExternalArrayElementSize(ExternalArrayType type)2035 size_t GetExternalArrayElementSize(ExternalArrayType type) {
2036   switch (type) {
2037 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
2038   case kExternal##Type##Array:                          \
2039     return size;
2040     TYPED_ARRAYS(TYPED_ARRAY_CASE)
2041     default:
2042       UNREACHABLE();
2043       return 0;
2044   }
2045 #undef TYPED_ARRAY_CASE
2046 }
2047 
2048 
GetFixedTypedArraysElementSize(ElementsKind kind)2049 size_t GetFixedTypedArraysElementSize(ElementsKind kind) {
2050   switch (kind) {
2051 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
2052   case TYPE##_ELEMENTS:                                 \
2053     return size;
2054     TYPED_ARRAYS(TYPED_ARRAY_CASE)
2055     default:
2056       UNREACHABLE();
2057       return 0;
2058   }
2059 #undef TYPED_ARRAY_CASE
2060 }
2061 
2062 
GetArrayTypeFromElementsKind(ElementsKind kind)2063 ExternalArrayType GetArrayTypeFromElementsKind(ElementsKind kind) {
2064   switch (kind) {
2065 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
2066   case TYPE##_ELEMENTS:                                 \
2067     return kExternal##Type##Array;
2068     TYPED_ARRAYS(TYPED_ARRAY_CASE)
2069     default:
2070       UNREACHABLE();
2071       return kExternalInt8Array;
2072   }
2073 #undef TYPED_ARRAY_CASE
2074 }
2075 
2076 
GetTypedArrayFun(ExternalArrayType type,Isolate * isolate)2077 JSFunction* GetTypedArrayFun(ExternalArrayType type, Isolate* isolate) {
2078   Context* native_context = isolate->context()->native_context();
2079   switch (type) {
2080 #define TYPED_ARRAY_FUN(Type, type, TYPE, ctype, size)                        \
2081     case kExternal##Type##Array:                                              \
2082       return native_context->type##_array_fun();
2083 
2084     TYPED_ARRAYS(TYPED_ARRAY_FUN)
2085 #undef TYPED_ARRAY_FUN
2086 
2087     default:
2088       UNREACHABLE();
2089       return NULL;
2090   }
2091 }
2092 
2093 
GetTypedArrayFun(ElementsKind elements_kind,Isolate * isolate)2094 JSFunction* GetTypedArrayFun(ElementsKind elements_kind, Isolate* isolate) {
2095   Context* native_context = isolate->context()->native_context();
2096   switch (elements_kind) {
2097 #define TYPED_ARRAY_FUN(Type, type, TYPE, ctype, size) \
2098   case TYPE##_ELEMENTS:                                \
2099     return native_context->type##_array_fun();
2100 
2101     TYPED_ARRAYS(TYPED_ARRAY_FUN)
2102 #undef TYPED_ARRAY_FUN
2103 
2104     default:
2105       UNREACHABLE();
2106       return NULL;
2107   }
2108 }
2109 
2110 
SetupArrayBufferView(i::Isolate * isolate,i::Handle<i::JSArrayBufferView> obj,i::Handle<i::JSArrayBuffer> buffer,size_t byte_offset,size_t byte_length,PretenureFlag pretenure=NOT_TENURED)2111 void SetupArrayBufferView(i::Isolate* isolate,
2112                           i::Handle<i::JSArrayBufferView> obj,
2113                           i::Handle<i::JSArrayBuffer> buffer,
2114                           size_t byte_offset, size_t byte_length,
2115                           PretenureFlag pretenure = NOT_TENURED) {
2116   DCHECK(byte_offset + byte_length <=
2117          static_cast<size_t>(buffer->byte_length()->Number()));
2118 
2119   DCHECK_EQ(obj->GetInternalFieldCount(),
2120             v8::ArrayBufferView::kInternalFieldCount);
2121   for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) {
2122     obj->SetInternalField(i, Smi::kZero);
2123   }
2124 
2125   obj->set_buffer(*buffer);
2126 
2127   i::Handle<i::Object> byte_offset_object =
2128       isolate->factory()->NewNumberFromSize(byte_offset, pretenure);
2129   obj->set_byte_offset(*byte_offset_object);
2130 
2131   i::Handle<i::Object> byte_length_object =
2132       isolate->factory()->NewNumberFromSize(byte_length, pretenure);
2133   obj->set_byte_length(*byte_length_object);
2134 }
2135 
2136 
2137 }  // namespace
2138 
2139 
NewJSTypedArray(ExternalArrayType type,PretenureFlag pretenure)2140 Handle<JSTypedArray> Factory::NewJSTypedArray(ExternalArrayType type,
2141                                               PretenureFlag pretenure) {
2142   Handle<JSFunction> typed_array_fun_handle(GetTypedArrayFun(type, isolate()));
2143 
2144   CALL_HEAP_FUNCTION(isolate(), isolate()->heap()->AllocateJSObject(
2145                                     *typed_array_fun_handle, pretenure),
2146                      JSTypedArray);
2147 }
2148 
2149 
NewJSTypedArray(ElementsKind elements_kind,PretenureFlag pretenure)2150 Handle<JSTypedArray> Factory::NewJSTypedArray(ElementsKind elements_kind,
2151                                               PretenureFlag pretenure) {
2152   Handle<JSFunction> typed_array_fun_handle(
2153       GetTypedArrayFun(elements_kind, isolate()));
2154 
2155   CALL_HEAP_FUNCTION(isolate(), isolate()->heap()->AllocateJSObject(
2156                                     *typed_array_fun_handle, pretenure),
2157                      JSTypedArray);
2158 }
2159 
2160 
NewJSTypedArray(ExternalArrayType type,Handle<JSArrayBuffer> buffer,size_t byte_offset,size_t length,PretenureFlag pretenure)2161 Handle<JSTypedArray> Factory::NewJSTypedArray(ExternalArrayType type,
2162                                               Handle<JSArrayBuffer> buffer,
2163                                               size_t byte_offset, size_t length,
2164                                               PretenureFlag pretenure) {
2165   Handle<JSTypedArray> obj = NewJSTypedArray(type, pretenure);
2166 
2167   size_t element_size = GetExternalArrayElementSize(type);
2168   ElementsKind elements_kind = GetExternalArrayElementsKind(type);
2169 
2170   CHECK(byte_offset % element_size == 0);
2171 
2172   CHECK(length <= (std::numeric_limits<size_t>::max() / element_size));
2173   CHECK(length <= static_cast<size_t>(Smi::kMaxValue));
2174   size_t byte_length = length * element_size;
2175   SetupArrayBufferView(isolate(), obj, buffer, byte_offset, byte_length,
2176                        pretenure);
2177 
2178   Handle<Object> length_object = NewNumberFromSize(length, pretenure);
2179   obj->set_length(*length_object);
2180 
2181   Handle<FixedTypedArrayBase> elements = NewFixedTypedArrayWithExternalPointer(
2182       static_cast<int>(length), type,
2183       static_cast<uint8_t*>(buffer->backing_store()) + byte_offset, pretenure);
2184   Handle<Map> map = JSObject::GetElementsTransitionMap(obj, elements_kind);
2185   JSObject::SetMapAndElements(obj, map, elements);
2186   return obj;
2187 }
2188 
2189 
NewJSTypedArray(ElementsKind elements_kind,size_t number_of_elements,PretenureFlag pretenure)2190 Handle<JSTypedArray> Factory::NewJSTypedArray(ElementsKind elements_kind,
2191                                               size_t number_of_elements,
2192                                               PretenureFlag pretenure) {
2193   Handle<JSTypedArray> obj = NewJSTypedArray(elements_kind, pretenure);
2194   DCHECK_EQ(obj->GetInternalFieldCount(),
2195             v8::ArrayBufferView::kInternalFieldCount);
2196   for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) {
2197     obj->SetInternalField(i, Smi::kZero);
2198   }
2199 
2200   size_t element_size = GetFixedTypedArraysElementSize(elements_kind);
2201   ExternalArrayType array_type = GetArrayTypeFromElementsKind(elements_kind);
2202 
2203   CHECK(number_of_elements <=
2204         (std::numeric_limits<size_t>::max() / element_size));
2205   CHECK(number_of_elements <= static_cast<size_t>(Smi::kMaxValue));
2206   size_t byte_length = number_of_elements * element_size;
2207 
2208   obj->set_byte_offset(Smi::kZero);
2209   i::Handle<i::Object> byte_length_object =
2210       NewNumberFromSize(byte_length, pretenure);
2211   obj->set_byte_length(*byte_length_object);
2212   Handle<Object> length_object =
2213       NewNumberFromSize(number_of_elements, pretenure);
2214   obj->set_length(*length_object);
2215 
2216   Handle<JSArrayBuffer> buffer =
2217       NewJSArrayBuffer(SharedFlag::kNotShared, pretenure);
2218   JSArrayBuffer::Setup(buffer, isolate(), true, NULL, byte_length,
2219                        SharedFlag::kNotShared);
2220   obj->set_buffer(*buffer);
2221   Handle<FixedTypedArrayBase> elements = NewFixedTypedArray(
2222       static_cast<int>(number_of_elements), array_type, true, pretenure);
2223   obj->set_elements(*elements);
2224   return obj;
2225 }
2226 
2227 
NewJSDataView(Handle<JSArrayBuffer> buffer,size_t byte_offset,size_t byte_length)2228 Handle<JSDataView> Factory::NewJSDataView(Handle<JSArrayBuffer> buffer,
2229                                           size_t byte_offset,
2230                                           size_t byte_length) {
2231   Handle<JSDataView> obj = NewJSDataView();
2232   SetupArrayBufferView(isolate(), obj, buffer, byte_offset, byte_length);
2233   return obj;
2234 }
2235 
2236 
NewJSBoundFunction(Handle<JSReceiver> target_function,Handle<Object> bound_this,Vector<Handle<Object>> bound_args)2237 MaybeHandle<JSBoundFunction> Factory::NewJSBoundFunction(
2238     Handle<JSReceiver> target_function, Handle<Object> bound_this,
2239     Vector<Handle<Object>> bound_args) {
2240   DCHECK(target_function->IsCallable());
2241   STATIC_ASSERT(Code::kMaxArguments <= FixedArray::kMaxLength);
2242   if (bound_args.length() >= Code::kMaxArguments) {
2243     THROW_NEW_ERROR(isolate(),
2244                     NewRangeError(MessageTemplate::kTooManyArguments),
2245                     JSBoundFunction);
2246   }
2247 
2248   // Determine the prototype of the {target_function}.
2249   Handle<Object> prototype;
2250   ASSIGN_RETURN_ON_EXCEPTION(
2251       isolate(), prototype,
2252       JSReceiver::GetPrototype(isolate(), target_function), JSBoundFunction);
2253 
2254   // Create the [[BoundArguments]] for the result.
2255   Handle<FixedArray> bound_arguments;
2256   if (bound_args.length() == 0) {
2257     bound_arguments = empty_fixed_array();
2258   } else {
2259     bound_arguments = NewFixedArray(bound_args.length());
2260     for (int i = 0; i < bound_args.length(); ++i) {
2261       bound_arguments->set(i, *bound_args[i]);
2262     }
2263   }
2264 
2265   // Setup the map for the JSBoundFunction instance.
2266   Handle<Map> map = target_function->IsConstructor()
2267                         ? isolate()->bound_function_with_constructor_map()
2268                         : isolate()->bound_function_without_constructor_map();
2269   if (map->prototype() != *prototype) {
2270     map = Map::TransitionToPrototype(map, prototype, REGULAR_PROTOTYPE);
2271   }
2272   DCHECK_EQ(target_function->IsConstructor(), map->is_constructor());
2273 
2274   // Setup the JSBoundFunction instance.
2275   Handle<JSBoundFunction> result =
2276       Handle<JSBoundFunction>::cast(NewJSObjectFromMap(map));
2277   result->set_bound_target_function(*target_function);
2278   result->set_bound_this(*bound_this);
2279   result->set_bound_arguments(*bound_arguments);
2280   return result;
2281 }
2282 
2283 
2284 // ES6 section 9.5.15 ProxyCreate (target, handler)
NewJSProxy(Handle<JSReceiver> target,Handle<JSReceiver> handler)2285 Handle<JSProxy> Factory::NewJSProxy(Handle<JSReceiver> target,
2286                                     Handle<JSReceiver> handler) {
2287   // Allocate the proxy object.
2288   Handle<Map> map;
2289   if (target->IsCallable()) {
2290     if (target->IsConstructor()) {
2291       map = Handle<Map>(isolate()->proxy_constructor_map());
2292     } else {
2293       map = Handle<Map>(isolate()->proxy_callable_map());
2294     }
2295   } else {
2296     map = Handle<Map>(isolate()->proxy_map());
2297   }
2298   DCHECK(map->prototype()->IsNull(isolate()));
2299   Handle<JSProxy> result = New<JSProxy>(map, NEW_SPACE);
2300   result->initialize_properties();
2301   result->set_target(*target);
2302   result->set_handler(*handler);
2303   result->set_hash(*undefined_value(), SKIP_WRITE_BARRIER);
2304   return result;
2305 }
2306 
NewUninitializedJSGlobalProxy(int size)2307 Handle<JSGlobalProxy> Factory::NewUninitializedJSGlobalProxy(int size) {
2308   // Create an empty shell of a JSGlobalProxy that needs to be reinitialized
2309   // via ReinitializeJSGlobalProxy later.
2310   Handle<Map> map = NewMap(JS_GLOBAL_PROXY_TYPE, size);
2311   // Maintain invariant expected from any JSGlobalProxy.
2312   map->set_is_access_check_needed(true);
2313   CALL_HEAP_FUNCTION(
2314       isolate(), isolate()->heap()->AllocateJSObjectFromMap(*map, NOT_TENURED),
2315       JSGlobalProxy);
2316 }
2317 
2318 
ReinitializeJSGlobalProxy(Handle<JSGlobalProxy> object,Handle<JSFunction> constructor)2319 void Factory::ReinitializeJSGlobalProxy(Handle<JSGlobalProxy> object,
2320                                         Handle<JSFunction> constructor) {
2321   DCHECK(constructor->has_initial_map());
2322   Handle<Map> map(constructor->initial_map(), isolate());
2323   Handle<Map> old_map(object->map(), isolate());
2324 
2325   // The proxy's hash should be retained across reinitialization.
2326   Handle<Object> hash(object->hash(), isolate());
2327 
2328   if (old_map->is_prototype_map()) {
2329     map = Map::Copy(map, "CopyAsPrototypeForJSGlobalProxy");
2330     map->set_is_prototype_map(true);
2331   }
2332   JSObject::NotifyMapChange(old_map, map, isolate());
2333   old_map->NotifyLeafMapLayoutChange();
2334 
2335   // Check that the already allocated object has the same size and type as
2336   // objects allocated using the constructor.
2337   DCHECK(map->instance_size() == old_map->instance_size());
2338   DCHECK(map->instance_type() == old_map->instance_type());
2339 
2340   // Allocate the backing storage for the properties.
2341   Handle<FixedArray> properties = empty_fixed_array();
2342 
2343   // In order to keep heap in consistent state there must be no allocations
2344   // before object re-initialization is finished.
2345   DisallowHeapAllocation no_allocation;
2346 
2347   // Reset the map for the object.
2348   object->synchronized_set_map(*map);
2349 
2350   Heap* heap = isolate()->heap();
2351   // Reinitialize the object from the constructor map.
2352   heap->InitializeJSObjectFromMap(*object, *properties, *map);
2353 
2354   // Restore the saved hash.
2355   object->set_hash(*hash);
2356 }
2357 
NewSharedFunctionInfo(Handle<String> name,FunctionKind kind,Handle<Code> code,Handle<ScopeInfo> scope_info)2358 Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo(
2359     Handle<String> name, FunctionKind kind, Handle<Code> code,
2360     Handle<ScopeInfo> scope_info) {
2361   DCHECK(IsValidFunctionKind(kind));
2362   Handle<SharedFunctionInfo> shared = NewSharedFunctionInfo(
2363       name, code, IsConstructable(kind, scope_info->language_mode()));
2364   shared->set_scope_info(*scope_info);
2365   shared->set_outer_scope_info(*the_hole_value());
2366   shared->set_kind(kind);
2367   if (IsGeneratorFunction(kind)) {
2368     shared->set_instance_class_name(isolate()->heap()->Generator_string());
2369   }
2370   return shared;
2371 }
2372 
NewSharedFunctionInfoForLiteral(FunctionLiteral * literal,Handle<Script> script)2373 Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfoForLiteral(
2374     FunctionLiteral* literal, Handle<Script> script) {
2375   Handle<Code> code = isolate()->builtins()->CompileLazy();
2376   Handle<ScopeInfo> scope_info(ScopeInfo::Empty(isolate()));
2377   Handle<SharedFunctionInfo> result =
2378       NewSharedFunctionInfo(literal->name(), literal->kind(), code, scope_info);
2379   SharedFunctionInfo::InitFromFunctionLiteral(result, literal);
2380   SharedFunctionInfo::SetScript(result, script);
2381   return result;
2382 }
2383 
NewJSMessageObject(MessageTemplate::Template message,Handle<Object> argument,int start_position,int end_position,Handle<Object> script,Handle<Object> stack_frames)2384 Handle<JSMessageObject> Factory::NewJSMessageObject(
2385     MessageTemplate::Template message, Handle<Object> argument,
2386     int start_position, int end_position, Handle<Object> script,
2387     Handle<Object> stack_frames) {
2388   Handle<Map> map = message_object_map();
2389   Handle<JSMessageObject> message_obj = New<JSMessageObject>(map, NEW_SPACE);
2390   message_obj->set_properties(*empty_fixed_array(), SKIP_WRITE_BARRIER);
2391   message_obj->initialize_elements();
2392   message_obj->set_elements(*empty_fixed_array(), SKIP_WRITE_BARRIER);
2393   message_obj->set_type(message);
2394   message_obj->set_argument(*argument);
2395   message_obj->set_start_position(start_position);
2396   message_obj->set_end_position(end_position);
2397   message_obj->set_script(*script);
2398   message_obj->set_stack_frames(*stack_frames);
2399   message_obj->set_error_level(v8::Isolate::kMessageError);
2400   return message_obj;
2401 }
2402 
2403 
NewSharedFunctionInfo(Handle<String> name,MaybeHandle<Code> maybe_code,bool is_constructor)2404 Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo(
2405     Handle<String> name, MaybeHandle<Code> maybe_code, bool is_constructor) {
2406   // Function names are assumed to be flat elsewhere. Must flatten before
2407   // allocating SharedFunctionInfo to avoid GC seeing the uninitialized SFI.
2408   name = String::Flatten(name, TENURED);
2409 
2410   Handle<Map> map = shared_function_info_map();
2411   Handle<SharedFunctionInfo> share = New<SharedFunctionInfo>(map, OLD_SPACE);
2412 
2413   // Set pointer fields.
2414   share->set_name(*name);
2415   share->set_function_data(*undefined_value(), SKIP_WRITE_BARRIER);
2416   Handle<Code> code;
2417   if (!maybe_code.ToHandle(&code)) {
2418     code = isolate()->builtins()->Illegal();
2419   }
2420   share->set_code(*code);
2421   share->set_optimized_code_map(*empty_fixed_array());
2422   share->set_scope_info(ScopeInfo::Empty(isolate()));
2423   share->set_outer_scope_info(*the_hole_value());
2424   Handle<Code> construct_stub =
2425       is_constructor ? isolate()->builtins()->JSConstructStubGeneric()
2426                      : isolate()->builtins()->ConstructedNonConstructable();
2427   share->SetConstructStub(*construct_stub);
2428   share->set_instance_class_name(*Object_string());
2429   share->set_script(*undefined_value(), SKIP_WRITE_BARRIER);
2430   share->set_debug_info(Smi::kZero, SKIP_WRITE_BARRIER);
2431   share->set_function_identifier(*undefined_value(), SKIP_WRITE_BARRIER);
2432   StaticFeedbackVectorSpec empty_spec;
2433   Handle<FeedbackMetadata> feedback_metadata =
2434       FeedbackMetadata::New(isolate(), &empty_spec);
2435   share->set_feedback_metadata(*feedback_metadata, SKIP_WRITE_BARRIER);
2436   share->set_function_literal_id(FunctionLiteral::kIdTypeInvalid);
2437 #if TRACE_MAPS
2438   share->set_unique_id(isolate()->GetNextUniqueSharedFunctionInfoId());
2439 #endif
2440   share->set_profiler_ticks(0);
2441   share->set_ast_node_count(0);
2442   share->set_counters(0);
2443 
2444   // Set integer fields (smi or int, depending on the architecture).
2445   share->set_length(0);
2446   share->set_internal_formal_parameter_count(0);
2447   share->set_expected_nof_properties(0);
2448   share->set_start_position_and_type(0);
2449   share->set_end_position(0);
2450   share->set_function_token_position(0);
2451   // All compiler hints default to false or 0.
2452   share->set_compiler_hints(0);
2453   share->set_opt_count_and_bailout_reason(0);
2454 
2455   // Link into the list.
2456   Handle<Object> new_noscript_list =
2457       WeakFixedArray::Add(noscript_shared_function_infos(), share);
2458   isolate()->heap()->set_noscript_shared_function_infos(*new_noscript_list);
2459 
2460   return share;
2461 }
2462 
2463 
NumberCacheHash(Handle<FixedArray> cache,Handle<Object> number)2464 static inline int NumberCacheHash(Handle<FixedArray> cache,
2465                                   Handle<Object> number) {
2466   int mask = (cache->length() >> 1) - 1;
2467   if (number->IsSmi()) {
2468     return Handle<Smi>::cast(number)->value() & mask;
2469   } else {
2470     int64_t bits = bit_cast<int64_t>(number->Number());
2471     return (static_cast<int>(bits) ^ static_cast<int>(bits >> 32)) & mask;
2472   }
2473 }
2474 
2475 
GetNumberStringCache(Handle<Object> number)2476 Handle<Object> Factory::GetNumberStringCache(Handle<Object> number) {
2477   DisallowHeapAllocation no_gc;
2478   int hash = NumberCacheHash(number_string_cache(), number);
2479   Object* key = number_string_cache()->get(hash * 2);
2480   if (key == *number || (key->IsHeapNumber() && number->IsHeapNumber() &&
2481                          key->Number() == number->Number())) {
2482     return Handle<String>(
2483         String::cast(number_string_cache()->get(hash * 2 + 1)), isolate());
2484   }
2485   return undefined_value();
2486 }
2487 
2488 
SetNumberStringCache(Handle<Object> number,Handle<String> string)2489 void Factory::SetNumberStringCache(Handle<Object> number,
2490                                    Handle<String> string) {
2491   int hash = NumberCacheHash(number_string_cache(), number);
2492   if (number_string_cache()->get(hash * 2) != *undefined_value()) {
2493     int full_size = isolate()->heap()->FullSizeNumberStringCacheLength();
2494     if (number_string_cache()->length() != full_size) {
2495       Handle<FixedArray> new_cache = NewFixedArray(full_size, TENURED);
2496       isolate()->heap()->set_number_string_cache(*new_cache);
2497       return;
2498     }
2499   }
2500   number_string_cache()->set(hash * 2, *number);
2501   number_string_cache()->set(hash * 2 + 1, *string);
2502 }
2503 
2504 
NumberToString(Handle<Object> number,bool check_number_string_cache)2505 Handle<String> Factory::NumberToString(Handle<Object> number,
2506                                        bool check_number_string_cache) {
2507   isolate()->counters()->number_to_string_runtime()->Increment();
2508   if (check_number_string_cache) {
2509     Handle<Object> cached = GetNumberStringCache(number);
2510     if (!cached->IsUndefined(isolate())) return Handle<String>::cast(cached);
2511   }
2512 
2513   char arr[100];
2514   Vector<char> buffer(arr, arraysize(arr));
2515   const char* str;
2516   if (number->IsSmi()) {
2517     int num = Handle<Smi>::cast(number)->value();
2518     str = IntToCString(num, buffer);
2519   } else {
2520     double num = Handle<HeapNumber>::cast(number)->value();
2521     str = DoubleToCString(num, buffer);
2522   }
2523 
2524   // We tenure the allocated string since it is referenced from the
2525   // number-string cache which lives in the old space.
2526   Handle<String> js_string = NewStringFromAsciiChecked(str, TENURED);
2527   SetNumberStringCache(number, js_string);
2528   return js_string;
2529 }
2530 
2531 
NewDebugInfo(Handle<SharedFunctionInfo> shared)2532 Handle<DebugInfo> Factory::NewDebugInfo(Handle<SharedFunctionInfo> shared) {
2533   DCHECK(!shared->HasDebugInfo());
2534   // Allocate initial fixed array for active break points before allocating the
2535   // debug info object to avoid allocation while setting up the debug info
2536   // object.
2537   Handle<FixedArray> break_points(
2538       NewFixedArray(DebugInfo::kEstimatedNofBreakPointsInFunction));
2539 
2540   // Make a copy of the bytecode array if available.
2541   Handle<Object> maybe_debug_bytecode_array = undefined_value();
2542   if (shared->HasBytecodeArray()) {
2543     Handle<BytecodeArray> original(shared->bytecode_array());
2544     maybe_debug_bytecode_array = CopyBytecodeArray(original);
2545   }
2546 
2547   // Create and set up the debug info object. Debug info contains function, a
2548   // copy of the original code, the executing code and initial fixed array for
2549   // active break points.
2550   Handle<DebugInfo> debug_info =
2551       Handle<DebugInfo>::cast(NewStruct(DEBUG_INFO_TYPE));
2552   debug_info->set_shared(*shared);
2553   debug_info->set_debugger_hints(shared->debugger_hints());
2554   debug_info->set_debug_bytecode_array(*maybe_debug_bytecode_array);
2555   debug_info->set_break_points(*break_points);
2556 
2557   // Link debug info to function.
2558   shared->set_debug_info(*debug_info);
2559 
2560   return debug_info;
2561 }
2562 
NewBreakPointInfo(int source_position)2563 Handle<BreakPointInfo> Factory::NewBreakPointInfo(int source_position) {
2564   Handle<BreakPointInfo> new_break_point_info =
2565       Handle<BreakPointInfo>::cast(NewStruct(BREAK_POINT_INFO_TYPE));
2566   new_break_point_info->set_source_position(source_position);
2567   new_break_point_info->set_break_point_objects(*undefined_value());
2568   return new_break_point_info;
2569 }
2570 
NewArgumentsObject(Handle<JSFunction> callee,int length)2571 Handle<JSObject> Factory::NewArgumentsObject(Handle<JSFunction> callee,
2572                                              int length) {
2573   bool strict_mode_callee = is_strict(callee->shared()->language_mode()) ||
2574                             !callee->shared()->has_simple_parameters();
2575   Handle<Map> map = strict_mode_callee ? isolate()->strict_arguments_map()
2576                                        : isolate()->sloppy_arguments_map();
2577   AllocationSiteUsageContext context(isolate(), Handle<AllocationSite>(),
2578                                      false);
2579   DCHECK(!isolate()->has_pending_exception());
2580   Handle<JSObject> result = NewJSObjectFromMap(map);
2581   Handle<Smi> value(Smi::FromInt(length), isolate());
2582   Object::SetProperty(result, length_string(), value, STRICT).Assert();
2583   if (!strict_mode_callee) {
2584     Object::SetProperty(result, callee_string(), callee, STRICT).Assert();
2585   }
2586   return result;
2587 }
2588 
2589 
NewJSWeakMap()2590 Handle<JSWeakMap> Factory::NewJSWeakMap() {
2591   // TODO(adamk): Currently the map is only created three times per
2592   // isolate. If it's created more often, the map should be moved into the
2593   // strong root list.
2594   Handle<Map> map = NewMap(JS_WEAK_MAP_TYPE, JSWeakMap::kSize);
2595   return Handle<JSWeakMap>::cast(NewJSObjectFromMap(map));
2596 }
2597 
2598 
ObjectLiteralMapFromCache(Handle<Context> context,int number_of_properties,bool * is_result_from_cache)2599 Handle<Map> Factory::ObjectLiteralMapFromCache(Handle<Context> context,
2600                                                int number_of_properties,
2601                                                bool* is_result_from_cache) {
2602   const int kMapCacheSize = 128;
2603 
2604   // We do not cache maps for too many properties or when running builtin code.
2605   if (number_of_properties > kMapCacheSize ||
2606       isolate()->bootstrapper()->IsActive()) {
2607     *is_result_from_cache = false;
2608     Handle<Map> map = Map::Create(isolate(), number_of_properties);
2609     return map;
2610   }
2611   *is_result_from_cache = true;
2612   if (number_of_properties == 0) {
2613     // Reuse the initial map of the Object function if the literal has no
2614     // predeclared properties.
2615     return handle(context->object_function()->initial_map(), isolate());
2616   }
2617 
2618   int cache_index = number_of_properties - 1;
2619   Handle<Object> maybe_cache(context->map_cache(), isolate());
2620   if (maybe_cache->IsUndefined(isolate())) {
2621     // Allocate the new map cache for the native context.
2622     maybe_cache = NewFixedArray(kMapCacheSize, TENURED);
2623     context->set_map_cache(*maybe_cache);
2624   } else {
2625     // Check to see whether there is a matching element in the cache.
2626     Handle<FixedArray> cache = Handle<FixedArray>::cast(maybe_cache);
2627     Object* result = cache->get(cache_index);
2628     if (result->IsWeakCell()) {
2629       WeakCell* cell = WeakCell::cast(result);
2630       if (!cell->cleared()) {
2631         return handle(Map::cast(cell->value()), isolate());
2632       }
2633     }
2634   }
2635   // Create a new map and add it to the cache.
2636   Handle<FixedArray> cache = Handle<FixedArray>::cast(maybe_cache);
2637   Handle<Map> map = Map::Create(isolate(), number_of_properties);
2638   Handle<WeakCell> cell = NewWeakCell(map);
2639   cache->set(cache_index, *cell);
2640   return map;
2641 }
2642 
2643 
SetRegExpAtomData(Handle<JSRegExp> regexp,JSRegExp::Type type,Handle<String> source,JSRegExp::Flags flags,Handle<Object> data)2644 void Factory::SetRegExpAtomData(Handle<JSRegExp> regexp,
2645                                 JSRegExp::Type type,
2646                                 Handle<String> source,
2647                                 JSRegExp::Flags flags,
2648                                 Handle<Object> data) {
2649   Handle<FixedArray> store = NewFixedArray(JSRegExp::kAtomDataSize);
2650 
2651   store->set(JSRegExp::kTagIndex, Smi::FromInt(type));
2652   store->set(JSRegExp::kSourceIndex, *source);
2653   store->set(JSRegExp::kFlagsIndex, Smi::FromInt(flags));
2654   store->set(JSRegExp::kAtomPatternIndex, *data);
2655   regexp->set_data(*store);
2656 }
2657 
2658 
SetRegExpIrregexpData(Handle<JSRegExp> regexp,JSRegExp::Type type,Handle<String> source,JSRegExp::Flags flags,int capture_count)2659 void Factory::SetRegExpIrregexpData(Handle<JSRegExp> regexp,
2660                                     JSRegExp::Type type,
2661                                     Handle<String> source,
2662                                     JSRegExp::Flags flags,
2663                                     int capture_count) {
2664   Handle<FixedArray> store = NewFixedArray(JSRegExp::kIrregexpDataSize);
2665   Smi* uninitialized = Smi::FromInt(JSRegExp::kUninitializedValue);
2666   store->set(JSRegExp::kTagIndex, Smi::FromInt(type));
2667   store->set(JSRegExp::kSourceIndex, *source);
2668   store->set(JSRegExp::kFlagsIndex, Smi::FromInt(flags));
2669   store->set(JSRegExp::kIrregexpLatin1CodeIndex, uninitialized);
2670   store->set(JSRegExp::kIrregexpUC16CodeIndex, uninitialized);
2671   store->set(JSRegExp::kIrregexpLatin1CodeSavedIndex, uninitialized);
2672   store->set(JSRegExp::kIrregexpUC16CodeSavedIndex, uninitialized);
2673   store->set(JSRegExp::kIrregexpMaxRegisterCountIndex, Smi::kZero);
2674   store->set(JSRegExp::kIrregexpCaptureCountIndex,
2675              Smi::FromInt(capture_count));
2676   store->set(JSRegExp::kIrregexpCaptureNameMapIndex, uninitialized);
2677   regexp->set_data(*store);
2678 }
2679 
NewRegExpMatchInfo()2680 Handle<RegExpMatchInfo> Factory::NewRegExpMatchInfo() {
2681   // Initially, the last match info consists of all fixed fields plus space for
2682   // the match itself (i.e., 2 capture indices).
2683   static const int kInitialSize = RegExpMatchInfo::kFirstCaptureIndex +
2684                                   RegExpMatchInfo::kInitialCaptureIndices;
2685 
2686   Handle<FixedArray> elems = NewFixedArray(kInitialSize);
2687   Handle<RegExpMatchInfo> result = Handle<RegExpMatchInfo>::cast(elems);
2688 
2689   result->SetNumberOfCaptureRegisters(RegExpMatchInfo::kInitialCaptureIndices);
2690   result->SetLastSubject(*empty_string());
2691   result->SetLastInput(*undefined_value());
2692   result->SetCapture(0, 0);
2693   result->SetCapture(1, 0);
2694 
2695   return result;
2696 }
2697 
GlobalConstantFor(Handle<Name> name)2698 Handle<Object> Factory::GlobalConstantFor(Handle<Name> name) {
2699   if (Name::Equals(name, undefined_string())) return undefined_value();
2700   if (Name::Equals(name, nan_string())) return nan_value();
2701   if (Name::Equals(name, infinity_string())) return infinity_value();
2702   return Handle<Object>::null();
2703 }
2704 
2705 
ToBoolean(bool value)2706 Handle<Object> Factory::ToBoolean(bool value) {
2707   return value ? true_value() : false_value();
2708 }
2709 
ToPrimitiveHintString(ToPrimitiveHint hint)2710 Handle<String> Factory::ToPrimitiveHintString(ToPrimitiveHint hint) {
2711   switch (hint) {
2712     case ToPrimitiveHint::kDefault:
2713       return default_string();
2714     case ToPrimitiveHint::kNumber:
2715       return number_string();
2716     case ToPrimitiveHint::kString:
2717       return string_string();
2718   }
2719   UNREACHABLE();
2720   return Handle<String>::null();
2721 }
2722 
CreateSloppyFunctionMap(FunctionMode function_mode)2723 Handle<Map> Factory::CreateSloppyFunctionMap(FunctionMode function_mode) {
2724   Handle<Map> map = NewMap(JS_FUNCTION_TYPE, JSFunction::kSize);
2725   SetFunctionInstanceDescriptor(map, function_mode);
2726   map->set_is_constructor(IsFunctionModeWithPrototype(function_mode));
2727   map->set_is_callable();
2728   return map;
2729 }
2730 
SetFunctionInstanceDescriptor(Handle<Map> map,FunctionMode function_mode)2731 void Factory::SetFunctionInstanceDescriptor(Handle<Map> map,
2732                                             FunctionMode function_mode) {
2733   int size = IsFunctionModeWithPrototype(function_mode) ? 5 : 4;
2734   Map::EnsureDescriptorSlack(map, size);
2735 
2736   PropertyAttributes ro_attribs =
2737       static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
2738   PropertyAttributes roc_attribs =
2739       static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY);
2740 
2741   STATIC_ASSERT(JSFunction::kLengthDescriptorIndex == 0);
2742   Handle<AccessorInfo> length =
2743       Accessors::FunctionLengthInfo(isolate(), roc_attribs);
2744   {  // Add length.
2745     Descriptor d = Descriptor::AccessorConstant(
2746         Handle<Name>(Name::cast(length->name())), length, roc_attribs);
2747     map->AppendDescriptor(&d);
2748   }
2749 
2750   STATIC_ASSERT(JSFunction::kNameDescriptorIndex == 1);
2751   Handle<AccessorInfo> name =
2752       Accessors::FunctionNameInfo(isolate(), roc_attribs);
2753   {  // Add name.
2754     Descriptor d = Descriptor::AccessorConstant(
2755         Handle<Name>(Name::cast(name->name())), name, roc_attribs);
2756     map->AppendDescriptor(&d);
2757   }
2758   Handle<AccessorInfo> args =
2759       Accessors::FunctionArgumentsInfo(isolate(), ro_attribs);
2760   {  // Add arguments.
2761     Descriptor d = Descriptor::AccessorConstant(
2762         Handle<Name>(Name::cast(args->name())), args, ro_attribs);
2763     map->AppendDescriptor(&d);
2764   }
2765   Handle<AccessorInfo> caller =
2766       Accessors::FunctionCallerInfo(isolate(), ro_attribs);
2767   {  // Add caller.
2768     Descriptor d = Descriptor::AccessorConstant(
2769         Handle<Name>(Name::cast(caller->name())), caller, ro_attribs);
2770     map->AppendDescriptor(&d);
2771   }
2772   if (IsFunctionModeWithPrototype(function_mode)) {
2773     if (function_mode == FUNCTION_WITH_WRITEABLE_PROTOTYPE) {
2774       ro_attribs = static_cast<PropertyAttributes>(ro_attribs & ~READ_ONLY);
2775     }
2776     Handle<AccessorInfo> prototype =
2777         Accessors::FunctionPrototypeInfo(isolate(), ro_attribs);
2778     Descriptor d = Descriptor::AccessorConstant(
2779         Handle<Name>(Name::cast(prototype->name())), prototype, ro_attribs);
2780     map->AppendDescriptor(&d);
2781   }
2782 }
2783 
CreateStrictFunctionMap(FunctionMode function_mode,Handle<JSFunction> empty_function)2784 Handle<Map> Factory::CreateStrictFunctionMap(
2785     FunctionMode function_mode, Handle<JSFunction> empty_function) {
2786   Handle<Map> map = NewMap(JS_FUNCTION_TYPE, JSFunction::kSize);
2787   SetStrictFunctionInstanceDescriptor(map, function_mode);
2788   map->set_is_constructor(IsFunctionModeWithPrototype(function_mode));
2789   map->set_is_callable();
2790   Map::SetPrototype(map, empty_function);
2791   return map;
2792 }
2793 
SetStrictFunctionInstanceDescriptor(Handle<Map> map,FunctionMode function_mode)2794 void Factory::SetStrictFunctionInstanceDescriptor(Handle<Map> map,
2795                                                   FunctionMode function_mode) {
2796   int size = IsFunctionModeWithPrototype(function_mode) ? 3 : 2;
2797   Map::EnsureDescriptorSlack(map, size);
2798 
2799   PropertyAttributes rw_attribs =
2800       static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE);
2801   PropertyAttributes ro_attribs =
2802       static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
2803   PropertyAttributes roc_attribs =
2804       static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY);
2805 
2806   DCHECK(function_mode == FUNCTION_WITH_WRITEABLE_PROTOTYPE ||
2807          function_mode == FUNCTION_WITH_READONLY_PROTOTYPE ||
2808          function_mode == FUNCTION_WITHOUT_PROTOTYPE);
2809   STATIC_ASSERT(JSFunction::kLengthDescriptorIndex == 0);
2810   {  // Add length.
2811     Handle<AccessorInfo> length =
2812         Accessors::FunctionLengthInfo(isolate(), roc_attribs);
2813     Descriptor d = Descriptor::AccessorConstant(
2814         handle(Name::cast(length->name())), length, roc_attribs);
2815     map->AppendDescriptor(&d);
2816   }
2817 
2818   STATIC_ASSERT(JSFunction::kNameDescriptorIndex == 1);
2819   {  // Add name.
2820     Handle<AccessorInfo> name =
2821         Accessors::FunctionNameInfo(isolate(), roc_attribs);
2822     Descriptor d = Descriptor::AccessorConstant(
2823         handle(Name::cast(name->name())), name, roc_attribs);
2824     map->AppendDescriptor(&d);
2825   }
2826   if (IsFunctionModeWithPrototype(function_mode)) {
2827     // Add prototype.
2828     PropertyAttributes attribs =
2829         function_mode == FUNCTION_WITH_WRITEABLE_PROTOTYPE ? rw_attribs
2830                                                            : ro_attribs;
2831     Handle<AccessorInfo> prototype =
2832         Accessors::FunctionPrototypeInfo(isolate(), attribs);
2833     Descriptor d = Descriptor::AccessorConstant(
2834         Handle<Name>(Name::cast(prototype->name())), prototype, attribs);
2835     map->AppendDescriptor(&d);
2836   }
2837 }
2838 
CreateClassFunctionMap(Handle<JSFunction> empty_function)2839 Handle<Map> Factory::CreateClassFunctionMap(Handle<JSFunction> empty_function) {
2840   Handle<Map> map = NewMap(JS_FUNCTION_TYPE, JSFunction::kSize);
2841   SetClassFunctionInstanceDescriptor(map);
2842   map->set_is_constructor(true);
2843   map->set_is_callable();
2844   Map::SetPrototype(map, empty_function);
2845   return map;
2846 }
2847 
SetClassFunctionInstanceDescriptor(Handle<Map> map)2848 void Factory::SetClassFunctionInstanceDescriptor(Handle<Map> map) {
2849   Map::EnsureDescriptorSlack(map, 2);
2850 
2851   PropertyAttributes rw_attribs =
2852       static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE);
2853   PropertyAttributes roc_attribs =
2854       static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY);
2855 
2856   STATIC_ASSERT(JSFunction::kLengthDescriptorIndex == 0);
2857   {  // Add length.
2858     Handle<AccessorInfo> length =
2859         Accessors::FunctionLengthInfo(isolate(), roc_attribs);
2860     Descriptor d = Descriptor::AccessorConstant(
2861         handle(Name::cast(length->name())), length, roc_attribs);
2862     map->AppendDescriptor(&d);
2863   }
2864 
2865   {
2866     // Add prototype.
2867     Handle<AccessorInfo> prototype =
2868         Accessors::FunctionPrototypeInfo(isolate(), rw_attribs);
2869     Descriptor d = Descriptor::AccessorConstant(
2870         Handle<Name>(Name::cast(prototype->name())), prototype, rw_attribs);
2871     map->AppendDescriptor(&d);
2872   }
2873 }
2874 
2875 }  // namespace internal
2876 }  // namespace v8
2877