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