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