@@ -2730,6 +2730,110 @@ THREADED_TEST(InternalFields) {
27302730 CHECK_EQ(17, obj->GetInternalField(0)->Int32Value(env.local()).FromJust());
27312731}
27322732
2733+ TEST(InternalFieldsSubclassing) {
2734+ LocalContext env;
2735+ v8::Isolate* isolate = env->GetIsolate();
2736+ v8::HandleScope scope(isolate);
2737+ for (int nof_embedder_fields = 0;
2738+ nof_embedder_fields < i::JSObject::kMaxEmbedderFields;
2739+ nof_embedder_fields++) {
2740+ Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate);
2741+ Local<v8::ObjectTemplate> instance_templ = templ->InstanceTemplate();
2742+ instance_templ->SetInternalFieldCount(nof_embedder_fields);
2743+ Local<Function> constructor =
2744+ templ->GetFunction(env.local()).ToLocalChecked();
2745+ // Check that instances have the correct NOF properties.
2746+ Local<v8::Object> obj =
2747+ constructor->NewInstance(env.local()).ToLocalChecked();
2748+
2749+ i::Handle<i::JSObject> i_obj =
2750+ i::Handle<i::JSObject>::cast(v8::Utils::OpenHandle(*obj));
2751+ CHECK_EQ(nof_embedder_fields, obj->InternalFieldCount());
2752+ CHECK_EQ(0, i_obj->map()->GetInObjectProperties());
2753+ // Check writing and reading internal fields.
2754+ for (int j = 0; j < nof_embedder_fields; j++) {
2755+ CHECK(obj->GetInternalField(j)->IsUndefined());
2756+ int value = 17 + j;
2757+ obj->SetInternalField(j, v8_num(value));
2758+ }
2759+ for (int j = 0; j < nof_embedder_fields; j++) {
2760+ int value = 17 + j;
2761+ CHECK_EQ(value,
2762+ obj->GetInternalField(j)->Int32Value(env.local()).FromJust());
2763+ }
2764+ CHECK(env->Global()
2765+ ->Set(env.local(), v8_str("BaseClass"), constructor)
2766+ .FromJust());
2767+ // Create various levels of subclasses to stress instance size calculation.
2768+ const int kMaxNofProperties =
2769+ i::JSObject::kMaxInObjectProperties - nof_embedder_fields;
2770+ // Select only a few values to speed up the test.
2771+ int sizes[] = {0,
2772+ 1,
2773+ 2,
2774+ 3,
2775+ 4,
2776+ 5,
2777+ 6,
2778+ kMaxNofProperties / 4,
2779+ kMaxNofProperties / 2,
2780+ kMaxNofProperties - 2,
2781+ kMaxNofProperties - 1,
2782+ kMaxNofProperties + 1,
2783+ kMaxNofProperties + 2,
2784+ kMaxNofProperties * 2,
2785+ kMaxNofProperties * 2};
2786+ for (size_t i = 0; i < arraysize(sizes); i++) {
2787+ int nof_properties = sizes[i];
2788+ bool in_object_only = nof_properties <= kMaxNofProperties;
2789+ std::ostringstream src;
2790+ // Assembler source string for a subclass with {nof_properties}
2791+ // in-object properties.
2792+ src << "(function() {\n"
2793+ << " class SubClass extends BaseClass {\n"
2794+ << " constructor() {\n"
2795+ << " super();\n";
2796+ // Set {nof_properties} instance properties in the constructor.
2797+ for (int j = 0; j < nof_properties; j++) {
2798+ src << " this.property" << j << " = " << j << ";\n";
2799+ }
2800+ src << " }\n"
2801+ << " };\n"
2802+ << " let instance;\n"
2803+ << " for (let i = 0; i < 3; i++) {\n"
2804+ << " instance = new SubClass();\n"
2805+ << " }"
2806+ << " return instance;\n"
2807+ << "})();";
2808+ Local<v8::Object> value = CompileRun(src.str().c_str()).As<v8::Object>();
2809+
2810+ i::Handle<i::JSObject> i_value =
2811+ i::Handle<i::JSObject>::cast(v8::Utils::OpenHandle(*value));
2812+ #ifdef VERIFY_HEAP
2813+ i_value->HeapObjectVerify();
2814+ i_value->map()->HeapObjectVerify();
2815+ i_value->map()->FindRootMap()->HeapObjectVerify();
2816+ #endif
2817+ CHECK_EQ(nof_embedder_fields, value->InternalFieldCount());
2818+ if (in_object_only) {
2819+ CHECK_LE(nof_properties, i_value->map()->GetInObjectProperties());
2820+ } else {
2821+ CHECK_LE(kMaxNofProperties, i_value->map()->GetInObjectProperties());
2822+ }
2823+
2824+ // Make Sure we get the precise property count.
2825+ i_value->map()->FindRootMap()->CompleteInobjectSlackTracking();
2826+ // TODO(cbruni): fix accounting to make this condition true.
2827+ // CHECK_EQ(0, i_value->map()->UnusedPropertyFields());
2828+ if (in_object_only) {
2829+ CHECK_EQ(nof_properties, i_value->map()->GetInObjectProperties());
2830+ } else {
2831+ CHECK_LE(kMaxNofProperties, i_value->map()->GetInObjectProperties());
2832+ }
2833+ }
2834+ }
2835+ }
2836+
27332837THREADED_TEST(InternalFieldsOfRegularObjects) {
27342838 LocalContext env;
27352839 v8::Isolate* isolate = env->GetIsolate();
0 commit comments