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