Skip to content

Commit fe6598c

Browse files
rossbergCommit bot
authored andcommitted
[strong] Object literals create strong objects
R=dslomov@chromium.org BUG=v8:3956 LOG=N Review URL: https://codereview.chromium.org/1134333005 Cr-Commit-Position: refs/heads/master@{#28444}
1 parent 6c98bb1 commit fe6598c

14 files changed

Lines changed: 182 additions & 50 deletions

File tree

include/v8.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6673,7 +6673,7 @@ class Internals {
66736673
static const int kJSObjectHeaderSize = 3 * kApiPointerSize;
66746674
static const int kFixedArrayHeaderSize = 2 * kApiPointerSize;
66756675
static const int kContextHeaderSize = 2 * kApiPointerSize;
6676-
static const int kContextEmbedderDataIndex = 77;
6676+
static const int kContextEmbedderDataIndex = 78;
66776677
static const int kFullStringRepresentationMask = 0x07;
66786678
static const int kStringEncodingMask = 0x4;
66796679
static const int kExternalTwoByteRepresentationTag = 0x02;

src/ast.h

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1295,11 +1295,14 @@ class MaterializedLiteral : public Expression {
12951295
return depth_;
12961296
}
12971297

1298+
bool is_strong() const { return is_strong_; }
1299+
12981300
protected:
1299-
MaterializedLiteral(Zone* zone, int literal_index, int pos)
1301+
MaterializedLiteral(Zone* zone, int literal_index, bool is_strong, int pos)
13001302
: Expression(zone, pos),
13011303
literal_index_(literal_index),
13021304
is_simple_(false),
1305+
is_strong_(is_strong),
13031306
depth_(0) {}
13041307

13051308
// A materialized literal is simple if the values consist of only
@@ -1328,6 +1331,7 @@ class MaterializedLiteral : public Expression {
13281331
private:
13291332
int literal_index_;
13301333
bool is_simple_;
1334+
bool is_strong_;
13311335
int depth_;
13321336
};
13331337

@@ -1422,6 +1426,9 @@ class ObjectLiteral final : public MaterializedLiteral {
14221426
if (disable_mementos) {
14231427
flags |= kDisableMementos;
14241428
}
1429+
if (is_strong()) {
1430+
flags |= kIsStrong;
1431+
}
14251432
return flags;
14261433
}
14271434

@@ -1430,7 +1437,8 @@ class ObjectLiteral final : public MaterializedLiteral {
14301437
kFastElements = 1,
14311438
kHasFunction = 1 << 1,
14321439
kShallowProperties = 1 << 2,
1433-
kDisableMementos = 1 << 3
1440+
kDisableMementos = 1 << 3,
1441+
kIsStrong = 1 << 4
14341442
};
14351443

14361444
struct Accessors: public ZoneObject {
@@ -1450,8 +1458,9 @@ class ObjectLiteral final : public MaterializedLiteral {
14501458

14511459
protected:
14521460
ObjectLiteral(Zone* zone, ZoneList<Property*>* properties, int literal_index,
1453-
int boilerplate_properties, bool has_function, int pos)
1454-
: MaterializedLiteral(zone, literal_index, pos),
1461+
int boilerplate_properties, bool has_function,
1462+
bool is_strong, int pos)
1463+
: MaterializedLiteral(zone, literal_index, is_strong, pos),
14551464
properties_(properties),
14561465
boilerplate_properties_(boilerplate_properties),
14571466
fast_elements_(false),
@@ -1482,8 +1491,9 @@ class RegExpLiteral final : public MaterializedLiteral {
14821491

14831492
protected:
14841493
RegExpLiteral(Zone* zone, const AstRawString* pattern,
1485-
const AstRawString* flags, int literal_index, int pos)
1486-
: MaterializedLiteral(zone, literal_index, pos),
1494+
const AstRawString* flags, int literal_index, bool is_strong,
1495+
int pos)
1496+
: MaterializedLiteral(zone, literal_index, is_strong, pos),
14871497
pattern_(pattern),
14881498
flags_(flags) {
14891499
set_depth(1);
@@ -1528,19 +1538,24 @@ class ArrayLiteral final : public MaterializedLiteral {
15281538
if (disable_mementos) {
15291539
flags |= kDisableMementos;
15301540
}
1541+
if (is_strong()) {
1542+
flags |= kIsStrong;
1543+
}
15311544
return flags;
15321545
}
15331546

15341547
enum Flags {
15351548
kNoFlags = 0,
15361549
kShallowElements = 1,
1537-
kDisableMementos = 1 << 1
1550+
kDisableMementos = 1 << 1,
1551+
kIsStrong = 1 << 2
15381552
};
15391553

15401554
protected:
15411555
ArrayLiteral(Zone* zone, ZoneList<Expression*>* values, int literal_index,
1542-
int pos)
1543-
: MaterializedLiteral(zone, literal_index, pos), values_(values) {}
1556+
bool is_strong, int pos)
1557+
: MaterializedLiteral(zone, literal_index, is_strong, pos),
1558+
values_(values) {}
15441559
static int parent_num_ids() { return MaterializedLiteral::num_ids(); }
15451560

15461561
private:
@@ -3305,9 +3320,11 @@ class AstNodeFactory final BASE_EMBEDDED {
33053320
int literal_index,
33063321
int boilerplate_properties,
33073322
bool has_function,
3323+
bool is_strong,
33083324
int pos) {
33093325
return new (zone_) ObjectLiteral(zone_, properties, literal_index,
3310-
boilerplate_properties, has_function, pos);
3326+
boilerplate_properties, has_function,
3327+
is_strong, pos);
33113328
}
33123329

33133330
ObjectLiteral::Property* NewObjectLiteralProperty(
@@ -3328,14 +3345,18 @@ class AstNodeFactory final BASE_EMBEDDED {
33283345
RegExpLiteral* NewRegExpLiteral(const AstRawString* pattern,
33293346
const AstRawString* flags,
33303347
int literal_index,
3348+
bool is_strong,
33313349
int pos) {
3332-
return new (zone_) RegExpLiteral(zone_, pattern, flags, literal_index, pos);
3350+
return new (zone_) RegExpLiteral(zone_, pattern, flags, literal_index,
3351+
is_strong, pos);
33333352
}
33343353

33353354
ArrayLiteral* NewArrayLiteral(ZoneList<Expression*>* values,
33363355
int literal_index,
3356+
bool is_strong,
33373357
int pos) {
3338-
return new (zone_) ArrayLiteral(zone_, values, literal_index, pos);
3358+
return new (zone_) ArrayLiteral(zone_, values, literal_index, is_strong,
3359+
pos);
33393360
}
33403361

33413362
VariableProxy* NewVariableProxy(Variable* var,

src/bootstrapper.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1016,6 +1016,11 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> global_object,
10161016
ArrayConstructorStub array_constructor_stub(isolate);
10171017
Handle<Code> code = array_constructor_stub.GetCode();
10181018
array_function->shared()->set_construct_stub(*code);
1019+
1020+
Handle<Map> initial_strong_map =
1021+
Map::Copy(initial_map, "SetInstancePrototype");
1022+
initial_strong_map->set_is_strong(true);
1023+
CacheInitialJSArrayMaps(native_context(), initial_strong_map);
10191024
}
10201025

10211026
{ // --- N u m b e r ---

src/contexts.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ enum BindingFlags {
8585
V(INTERNAL_ARRAY_FUNCTION_INDEX, JSFunction, internal_array_function) \
8686
V(ARRAY_FUNCTION_INDEX, JSFunction, array_function) \
8787
V(JS_ARRAY_MAPS_INDEX, Object, js_array_maps) \
88+
V(JS_ARRAY_STRONG_MAPS_INDEX, Object, js_array_strong_maps) \
8889
V(DATE_FUNCTION_INDEX, JSFunction, date_function) \
8990
V(JSON_OBJECT_INDEX, JSObject, json_object) \
9091
V(REGEXP_FUNCTION_INDEX, JSFunction, regexp_function) \
@@ -341,6 +342,7 @@ class Context: public FixedArray {
341342
INTERNAL_ARRAY_FUNCTION_INDEX,
342343
ARRAY_FUNCTION_INDEX,
343344
JS_ARRAY_MAPS_INDEX,
345+
JS_ARRAY_STRONG_MAPS_INDEX,
344346
DATE_FUNCTION_INDEX,
345347
JSON_OBJECT_INDEX,
346348
REGEXP_FUNCTION_INDEX,

src/factory.cc

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2339,14 +2339,18 @@ Handle<JSWeakMap> Factory::NewJSWeakMap() {
23392339

23402340
Handle<Map> Factory::ObjectLiteralMapFromCache(Handle<Context> context,
23412341
int number_of_properties,
2342+
bool is_strong,
23422343
bool* is_result_from_cache) {
23432344
const int kMapCacheSize = 128;
23442345

23452346
// We do not cache maps for too many properties or when running builtin code.
2346-
if (number_of_properties > kMapCacheSize ||
2347+
// TODO(rossberg): cache strong maps properly
2348+
if (number_of_properties > kMapCacheSize || is_strong ||
23472349
isolate()->bootstrapper()->IsActive()) {
23482350
*is_result_from_cache = false;
2349-
return Map::Create(isolate(), number_of_properties);
2351+
Handle<Map> map = Map::Create(isolate(), number_of_properties);
2352+
if (is_strong) map->set_is_strong(true);
2353+
return map;
23502354
}
23512355
*is_result_from_cache = true;
23522356
if (number_of_properties == 0) {

src/factory.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -670,6 +670,7 @@ class Factory final {
670670
// native context.
671671
Handle<Map> ObjectLiteralMapFromCache(Handle<Context> context,
672672
int number_of_properties,
673+
bool is_strong,
673674
bool* is_result_from_cache);
674675

675676
// Creates a new FixedArray that holds the data associated with the

src/hydrogen.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5790,7 +5790,8 @@ void HOptimizedGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) {
57905790
ASSIGN_RETURN_ON_EXCEPTION_VALUE(
57915791
isolate(), raw_boilerplate,
57925792
Runtime::CreateArrayLiteralBoilerplate(
5793-
isolate(), literals, expr->constant_elements()),
5793+
isolate(), literals, expr->constant_elements(),
5794+
is_strong(function_language_mode())),
57945795
Bailout(kArrayBoilerplateCreationFailed));
57955796

57965797
boilerplate_object = Handle<JSObject>::cast(raw_boilerplate);

src/objects.cc

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3804,7 +3804,9 @@ Handle<Map> Map::TransitionElementsTo(Handle<Map> map,
38043804

38053805
Isolate* isolate = map->GetIsolate();
38063806
Context* native_context = isolate->context()->native_context();
3807-
Object* maybe_array_maps = native_context->js_array_maps();
3807+
Object* maybe_array_maps = map->is_strong()
3808+
? native_context->js_array_strong_maps()
3809+
: native_context->js_array_maps();
38083810
if (maybe_array_maps->IsFixedArray()) {
38093811
DisallowHeapAllocation no_gc;
38103812
FixedArray* array_maps = FixedArray::cast(maybe_array_maps);
@@ -10318,7 +10320,10 @@ Handle<Object> CacheInitialJSArrayMaps(
1031810320
maps->set(next_kind, *new_map);
1031910321
current_map = new_map;
1032010322
}
10321-
native_context->set_js_array_maps(*maps);
10323+
if (initial_map->is_strong())
10324+
native_context->set_js_array_strong_maps(*maps);
10325+
else
10326+
native_context->set_js_array_maps(*maps);
1032210327
return initial_map;
1032310328
}
1032410329

@@ -10353,13 +10358,18 @@ void JSFunction::SetInstancePrototype(Handle<JSFunction> function,
1035310358
JSFunction::SetInitialMap(function, new_map, value);
1035410359

1035510360
// If the function is used as the global Array function, cache the
10356-
// initial map (and transitioned versions) in the native context.
10361+
// updated initial maps (and transitioned versions) in the native context.
1035710362
Context* native_context = function->context()->native_context();
1035810363
Object* array_function =
1035910364
native_context->get(Context::ARRAY_FUNCTION_INDEX);
1036010365
if (array_function->IsJSFunction() &&
1036110366
*function == JSFunction::cast(array_function)) {
1036210367
CacheInitialJSArrayMaps(handle(native_context, isolate), new_map);
10368+
Handle<Map> new_strong_map =
10369+
Map::Copy(initial_map, "SetInstancePrototype");
10370+
new_strong_map->set_is_strong(true);
10371+
CacheInitialJSArrayMaps(handle(native_context, isolate),
10372+
new_strong_map);
1036310373
}
1036410374
}
1036510375

src/parser.cc

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5588,11 +5588,12 @@ Expression* Parser::CloseTemplateLiteral(TemplateLiteralState* state, int start,
55885588
ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(4, zone());
55895589
args->Add(factory()->NewArrayLiteral(
55905590
const_cast<ZoneList<Expression*>*>(cooked_strings),
5591-
cooked_idx, pos),
5591+
cooked_idx, is_strong(language_mode()), pos),
55925592
zone());
55935593
args->Add(
55945594
factory()->NewArrayLiteral(
5595-
const_cast<ZoneList<Expression*>*>(raw_strings), raw_idx, pos),
5595+
const_cast<ZoneList<Expression*>*>(raw_strings), raw_idx,
5596+
is_strong(language_mode()), pos),
55965597
zone());
55975598

55985599
// Ensure hash is suitable as a Smi value
@@ -5683,6 +5684,7 @@ ZoneList<v8::internal::Expression*>* Parser::PrepareSpreadArguments(
56835684
}
56845685
int literal_index = function_state_->NextMaterializedLiteralIndex();
56855686
args->Add(factory()->NewArrayLiteral(unspread, literal_index,
5687+
is_strong(language_mode()),
56865688
RelocInfo::kNoPosition),
56875689
zone());
56885690

src/preparser.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1352,11 +1352,13 @@ class PreParserFactory {
13521352
PreParserExpression NewRegExpLiteral(PreParserIdentifier js_pattern,
13531353
PreParserIdentifier js_flags,
13541354
int literal_index,
1355+
bool is_strong,
13551356
int pos) {
13561357
return PreParserExpression::Default();
13571358
}
13581359
PreParserExpression NewArrayLiteral(PreParserExpressionList values,
13591360
int literal_index,
1361+
bool is_strong,
13601362
int pos) {
13611363
return PreParserExpression::Default();
13621364
}
@@ -1377,6 +1379,7 @@ class PreParserFactory {
13771379
int literal_index,
13781380
int boilerplate_properties,
13791381
bool has_function,
1382+
bool is_strong,
13801383
int pos) {
13811384
return PreParserExpression::Default();
13821385
}
@@ -2230,7 +2233,8 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseRegExpLiteral(
22302233
}
22312234
IdentifierT js_flags = this->GetNextSymbol(scanner());
22322235
Next();
2233-
return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index, pos);
2236+
return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index,
2237+
is_strong(language_mode()), pos);
22342238
}
22352239

22362240

@@ -2496,7 +2500,8 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral(
24962500
// Update the scope information before the pre-parsing bailout.
24972501
int literal_index = function_state_->NextMaterializedLiteralIndex();
24982502

2499-
return factory()->NewArrayLiteral(values, literal_index, pos);
2503+
return factory()->NewArrayLiteral(values, literal_index,
2504+
is_strong(language_mode()), pos);
25002505
}
25012506

25022507

@@ -2752,6 +2757,7 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseObjectLiteral(
27522757
literal_index,
27532758
number_of_boilerplate_properties,
27542759
has_function,
2760+
is_strong(language_mode()),
27552761
pos);
27562762
}
27572763

0 commit comments

Comments
 (0)