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