OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 917 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
928 return ReferenceError("not_defined", name); | 928 return ReferenceError("not_defined", name); |
929 } | 929 } |
930 return *result; | 930 return *result; |
931 } | 931 } |
932 | 932 |
933 // Get the property. | 933 // Get the property. |
934 return object->GetProperty(*object, &lookup, *name, &attr); | 934 return object->GetProperty(*object, &lookup, *name, &attr); |
935 } | 935 } |
936 | 936 |
937 | 937 |
| 938 static bool AddOneReceiverMapIfMissing(MapHandleList* receiver_maps, |
| 939 Handle<Map> new_receiver_map) { |
| 940 ASSERT(!new_receiver_map.is_null()); |
| 941 for (int current = 0; current < receiver_maps->length(); ++current) { |
| 942 if (!receiver_maps->at(current).is_null() && |
| 943 receiver_maps->at(current).is_identical_to(new_receiver_map)) { |
| 944 return false; |
| 945 } |
| 946 } |
| 947 receiver_maps->Add(new_receiver_map); |
| 948 return true; |
| 949 } |
| 950 |
| 951 |
| 952 bool IC::UpdatePolymorphicIC(State state, |
| 953 StrictModeFlag strict_mode, |
| 954 Handle<JSObject> receiver, |
| 955 Handle<String> name, |
| 956 Handle<Code> code) { |
| 957 if (code->type() == Code::NORMAL) return false; |
| 958 if (target()->ic_state() == MONOMORPHIC && |
| 959 target()->type() == Code::NORMAL) { |
| 960 return false; |
| 961 } |
| 962 MapHandleList receiver_maps; |
| 963 CodeHandleList handlers; |
| 964 target()->FindAllMaps(&receiver_maps); |
| 965 int number_of_maps = receiver_maps.length(); |
| 966 if (number_of_maps == 0 || number_of_maps >= 4) return false; |
| 967 |
| 968 target()->FindAllCode(&handlers, receiver_maps.length()); |
| 969 |
| 970 if (!AddOneReceiverMapIfMissing(&receiver_maps, |
| 971 Handle<Map>(receiver->map()))) { |
| 972 return false; |
| 973 } |
| 974 |
| 975 handlers.Add(code); |
| 976 Handle<Code> ic = isolate()->stub_cache()->ComputePolymorphicIC( |
| 977 &receiver_maps, &handlers, name); |
| 978 set_target(*ic); |
| 979 return true; |
| 980 } |
| 981 |
| 982 |
| 983 void LoadIC::UpdateMonomorphicIC(Handle<JSObject> receiver, |
| 984 Handle<Code> handler, |
| 985 Handle<String> name) { |
| 986 if (handler->type() == Code::NORMAL) return set_target(*handler); |
| 987 Handle<Code> ic = isolate()->stub_cache()->ComputeMonomorphicIC( |
| 988 receiver, handler, name); |
| 989 set_target(*ic); |
| 990 } |
| 991 |
| 992 |
| 993 void KeyedLoadIC::UpdateMonomorphicIC(Handle<JSObject> receiver, |
| 994 Handle<Code> handler, |
| 995 Handle<String> name) { |
| 996 if (handler->type() == Code::NORMAL) return set_target(*handler); |
| 997 Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedMonomorphicIC( |
| 998 receiver, handler, name); |
| 999 set_target(*ic); |
| 1000 } |
| 1001 |
| 1002 |
938 void IC::PatchCache(State state, | 1003 void IC::PatchCache(State state, |
939 StrictModeFlag strict_mode, | 1004 StrictModeFlag strict_mode, |
940 Handle<JSObject> receiver, | 1005 Handle<JSObject> receiver, |
941 Handle<String> name, | 1006 Handle<String> name, |
942 Handle<Code> code) { | 1007 Handle<Code> code) { |
943 switch (state) { | 1008 switch (state) { |
944 case UNINITIALIZED: | 1009 case UNINITIALIZED: |
945 case PREMONOMORPHIC: | 1010 case PREMONOMORPHIC: |
946 case MONOMORPHIC_PROTOTYPE_FAILURE: | 1011 case MONOMORPHIC_PROTOTYPE_FAILURE: |
947 set_target(*code); | 1012 UpdateMonomorphicIC(receiver, code, name); |
948 break; | 1013 break; |
949 case MONOMORPHIC: | 1014 case MONOMORPHIC: |
950 // Only move to megamorphic if the target changes. | 1015 // Only move to megamorphic if the target changes. |
951 if (target() != *code) { | 1016 if (target() != *code) { |
952 // We are transitioning from monomorphic to megamorphic case. | 1017 if (target()->is_load_stub()) { |
953 // Place the current monomorphic stub and stub compiled for | 1018 if (UpdatePolymorphicIC(state, strict_mode, receiver, name, code)) { |
954 // the receiver into stub cache. | 1019 break; |
| 1020 } |
| 1021 } |
| 1022 // We are transitioning from monomorphic to megamorphic case. Place the |
| 1023 // stub compiled for the receiver into stub cache. |
955 Map* map = target()->FindFirstMap(); | 1024 Map* map = target()->FindFirstMap(); |
956 if (map != NULL) { | 1025 if (map != NULL) { |
957 UpdateMegamorphicCache(map, *name, target()); | 1026 UpdateMegamorphicCache(map, *name, target()); |
958 } | 1027 } |
959 UpdateMegamorphicCache(receiver->map(), *name, *code); | 1028 UpdateMegamorphicCache(receiver->map(), *name, *code); |
960 set_target((strict_mode == kStrictMode) | 1029 set_target((strict_mode == kStrictMode) |
961 ? *megamorphic_stub_strict() | 1030 ? *megamorphic_stub_strict() |
962 : *megamorphic_stub()); | 1031 : *megamorphic_stub()); |
963 } | 1032 } |
964 break; | 1033 break; |
965 case MEGAMORPHIC: | 1034 case MEGAMORPHIC: |
966 // Update the stub cache. | 1035 // Update the stub cache. |
967 UpdateMegamorphicCache(receiver->map(), *name, *code); | 1036 UpdateMegamorphicCache(receiver->map(), *name, *code); |
968 break; | 1037 break; |
969 case POLYMORPHIC: | 1038 case POLYMORPHIC: |
970 // When trying to patch a polymorphic stub with anything other than | 1039 if (target()->is_load_stub()) { |
971 // another polymorphic stub, go generic. | 1040 if (UpdatePolymorphicIC(state, strict_mode, receiver, name, code)) { |
972 // TODO(verwaest): Currently we always go generic since no polymorphic | 1041 break; |
973 // stubs enter this code path. Replace with proper updating once named | 1042 } |
974 // load/store can also be polymorphic. | 1043 MapHandleList receiver_maps; |
975 set_target((strict_mode == kStrictMode) | 1044 CodeHandleList handlers; |
976 ? *generic_stub_strict() | 1045 target()->FindAllMaps(&receiver_maps); |
977 : *generic_stub()); | 1046 target()->FindAllCode(&handlers, receiver_maps.length()); |
| 1047 for (int i = 0; i < receiver_maps.length(); i++) { |
| 1048 UpdateMegamorphicCache(*receiver_maps.at(i), *name, *handlers.at(i)); |
| 1049 } |
| 1050 UpdateMegamorphicCache(receiver->map(), *name, *code); |
| 1051 set_target(*megamorphic_stub()); |
| 1052 } else { |
| 1053 // When trying to patch a polymorphic keyed load/store element stub |
| 1054 // with anything other than another polymorphic stub, go generic. |
| 1055 set_target((strict_mode == kStrictMode) |
| 1056 ? *generic_stub_strict() |
| 1057 : *generic_stub()); |
| 1058 } |
978 break; | 1059 break; |
979 case DEBUG_STUB: | 1060 case DEBUG_STUB: |
980 break; | 1061 break; |
981 case GENERIC: | 1062 case GENERIC: |
982 UNREACHABLE(); | 1063 UNREACHABLE(); |
983 break; | 1064 break; |
984 } | 1065 } |
985 } | 1066 } |
986 | 1067 |
987 | 1068 |
| 1069 static void GetReceiverMapsForStub(Handle<Code> stub, |
| 1070 MapHandleList* result) { |
| 1071 ASSERT(stub->is_inline_cache_stub()); |
| 1072 switch (stub->ic_state()) { |
| 1073 case MONOMORPHIC: { |
| 1074 Map* map = stub->FindFirstMap(); |
| 1075 if (map != NULL) { |
| 1076 result->Add(Handle<Map>(map)); |
| 1077 } |
| 1078 break; |
| 1079 } |
| 1080 case POLYMORPHIC: { |
| 1081 AssertNoAllocation no_allocation; |
| 1082 int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); |
| 1083 for (RelocIterator it(*stub, mask); !it.done(); it.next()) { |
| 1084 RelocInfo* info = it.rinfo(); |
| 1085 Handle<Object> object(info->target_object(), stub->GetIsolate()); |
| 1086 if (object->IsString()) break; |
| 1087 ASSERT(object->IsMap()); |
| 1088 AddOneReceiverMapIfMissing(result, Handle<Map>::cast(object)); |
| 1089 } |
| 1090 break; |
| 1091 } |
| 1092 case MEGAMORPHIC: |
| 1093 break; |
| 1094 case UNINITIALIZED: |
| 1095 case PREMONOMORPHIC: |
| 1096 case MONOMORPHIC_PROTOTYPE_FAILURE: |
| 1097 case GENERIC: |
| 1098 case DEBUG_STUB: |
| 1099 UNREACHABLE(); |
| 1100 break; |
| 1101 } |
| 1102 } |
| 1103 |
| 1104 |
988 void LoadIC::UpdateCaches(LookupResult* lookup, | 1105 void LoadIC::UpdateCaches(LookupResult* lookup, |
989 State state, | 1106 State state, |
990 Handle<Object> object, | 1107 Handle<Object> object, |
991 Handle<String> name) { | 1108 Handle<String> name) { |
992 // Bail out if the result is not cacheable. | 1109 // Bail out if the result is not cacheable. |
993 if (!lookup->IsCacheable()) return; | 1110 if (!lookup->IsCacheable()) return; |
994 | 1111 |
995 // Loading properties from values is not common, so don't try to | 1112 // Loading properties from values is not common, so don't try to |
996 // deal with non-JS objects here. | 1113 // deal with non-JS objects here. |
997 if (!object->IsJSObject()) return; | 1114 if (!object->IsJSObject()) return; |
998 | 1115 |
999 Handle<JSObject> receiver = Handle<JSObject>::cast(object); | 1116 Handle<JSObject> receiver = Handle<JSObject>::cast(object); |
1000 Handle<Code> code; | 1117 Handle<Code> code; |
1001 if (state == UNINITIALIZED) { | 1118 if (state == UNINITIALIZED) { |
1002 // This is the first time we execute this inline cache. | 1119 // This is the first time we execute this inline cache. |
1003 // Set the target to the pre monomorphic stub to delay | 1120 // Set the target to the pre monomorphic stub to delay |
1004 // setting the monomorphic state. | 1121 // setting the monomorphic state. |
1005 code = pre_monomorphic_stub(); | 1122 code = pre_monomorphic_stub(); |
1006 } else { | 1123 } else { |
1007 code = ComputeLoadMonomorphic(lookup, receiver, name); | 1124 code = ComputeLoadHandler(lookup, receiver, name); |
1008 if (code.is_null()) return; | 1125 if (code.is_null()) return; |
1009 } | 1126 } |
1010 | 1127 |
1011 PatchCache(state, kNonStrictMode, receiver, name, code); | 1128 PatchCache(state, kNonStrictMode, receiver, name, code); |
1012 TRACE_IC("LoadIC", name, state, target()); | 1129 TRACE_IC("LoadIC", name, state, target()); |
1013 } | 1130 } |
1014 | 1131 |
1015 | 1132 |
1016 void IC::UpdateMegamorphicCache(Map* map, String* name, Code* code) { | 1133 void IC::UpdateMegamorphicCache(Map* map, String* name, Code* code) { |
1017 // Cache code holding map should be consistent with | 1134 // Cache code holding map should be consistent with |
1018 // GenerateMonomorphicCacheProbe. | 1135 // GenerateMonomorphicCacheProbe. |
1019 isolate()->stub_cache()->Set(name, map, code); | 1136 isolate()->stub_cache()->Set(name, map, code); |
1020 } | 1137 } |
1021 | 1138 |
1022 | 1139 |
1023 Handle<Code> LoadIC::ComputeLoadMonomorphic(LookupResult* lookup, | 1140 Handle<Code> LoadIC::ComputeLoadHandler(LookupResult* lookup, |
1024 Handle<JSObject> receiver, | 1141 Handle<JSObject> receiver, |
1025 Handle<String> name) { | 1142 Handle<String> name) { |
1026 if (!lookup->IsProperty()) { | 1143 if (!lookup->IsProperty()) { |
1027 // Nonexistent property. The result is undefined. | 1144 // Nonexistent property. The result is undefined. |
1028 return isolate()->stub_cache()->ComputeLoadNonexistent(name, receiver); | 1145 return isolate()->stub_cache()->ComputeLoadNonexistent(name, receiver); |
1029 } | 1146 } |
1030 | 1147 |
1031 // Compute monomorphic stub. | 1148 // Compute monomorphic stub. |
1032 Handle<JSObject> holder(lookup->holder()); | 1149 Handle<JSObject> holder(lookup->holder()); |
1033 switch (lookup->type()) { | 1150 switch (lookup->type()) { |
1034 case FIELD: | 1151 case FIELD: |
1035 return isolate()->stub_cache()->ComputeLoadField( | 1152 return isolate()->stub_cache()->ComputeLoadField( |
1036 name, receiver, holder, lookup->GetFieldIndex()); | 1153 name, receiver, holder, lookup->GetFieldIndex()); |
1037 case CONSTANT_FUNCTION: { | 1154 case CONSTANT_FUNCTION: { |
1038 Handle<JSFunction> constant(lookup->GetConstantFunction()); | 1155 Handle<JSFunction> constant(lookup->GetConstantFunction()); |
1039 return isolate()->stub_cache()->ComputeLoadConstant( | 1156 return isolate()->stub_cache()->ComputeLoadConstant( |
1040 name, receiver, holder, constant); | 1157 name, receiver, holder, constant); |
1041 } | 1158 } |
1042 case NORMAL: | 1159 case NORMAL: |
1043 if (holder->IsGlobalObject()) { | 1160 if (holder->IsGlobalObject()) { |
1044 Handle<GlobalObject> global = Handle<GlobalObject>::cast(holder); | 1161 Handle<GlobalObject> global = Handle<GlobalObject>::cast(holder); |
1045 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(lookup)); | 1162 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(lookup)); |
1046 return isolate()->stub_cache()->ComputeLoadGlobal( | 1163 return isolate()->stub_cache()->ComputeLoadGlobal( |
1047 name, receiver, global, cell, lookup->IsDontDelete()); | 1164 name, receiver, global, cell, lookup->IsDontDelete()); |
1048 } | 1165 } |
1049 // There is only one shared stub for loading normalized | 1166 // There is only one shared stub for loading normalized |
1050 // properties. It does not traverse the prototype chain, so the | 1167 // properties. It does not traverse the prototype chain, so the |
1051 // property must be found in the receiver for the stub to be | 1168 // property must be found in the receiver for the stub to be |
1052 // applicable. | 1169 // applicable. |
1053 if (!holder.is_identical_to(receiver)) break; | 1170 if (!holder.is_identical_to(receiver)) break; |
1054 return isolate()->stub_cache()->ComputeLoadNormal(); | 1171 return isolate()->stub_cache()->ComputeLoadNormal(name, receiver); |
1055 case CALLBACKS: { | 1172 case CALLBACKS: { |
1056 Handle<Object> callback(lookup->GetCallbackObject(), isolate()); | 1173 Handle<Object> callback(lookup->GetCallbackObject(), isolate()); |
1057 if (callback->IsExecutableAccessorInfo()) { | 1174 if (callback->IsExecutableAccessorInfo()) { |
1058 Handle<ExecutableAccessorInfo> info = | 1175 Handle<ExecutableAccessorInfo> info = |
1059 Handle<ExecutableAccessorInfo>::cast(callback); | 1176 Handle<ExecutableAccessorInfo>::cast(callback); |
1060 if (v8::ToCData<Address>(info->getter()) == 0) break; | 1177 if (v8::ToCData<Address>(info->getter()) == 0) break; |
1061 if (!info->IsCompatibleReceiver(*receiver)) break; | 1178 if (!info->IsCompatibleReceiver(*receiver)) break; |
1062 return isolate()->stub_cache()->ComputeLoadCallback( | 1179 return isolate()->stub_cache()->ComputeLoadCallback( |
1063 name, receiver, holder, info); | 1180 name, receiver, holder, info); |
1064 } else if (callback->IsAccessorPair()) { | 1181 } else if (callback->IsAccessorPair()) { |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1100 key = Handle<Smi>(Smi::FromInt(int_value), isolate); | 1217 key = Handle<Smi>(Smi::FromInt(int_value), isolate); |
1101 } | 1218 } |
1102 } | 1219 } |
1103 } else if (key->IsUndefined()) { | 1220 } else if (key->IsUndefined()) { |
1104 key = isolate->factory()->undefined_string(); | 1221 key = isolate->factory()->undefined_string(); |
1105 } | 1222 } |
1106 return key; | 1223 return key; |
1107 } | 1224 } |
1108 | 1225 |
1109 | 1226 |
1110 static bool AddOneReceiverMapIfMissing(MapHandleList* receiver_maps, | |
1111 Handle<Map> new_receiver_map) { | |
1112 ASSERT(!new_receiver_map.is_null()); | |
1113 for (int current = 0; current < receiver_maps->length(); ++current) { | |
1114 if (!receiver_maps->at(current).is_null() && | |
1115 receiver_maps->at(current).is_identical_to(new_receiver_map)) { | |
1116 return false; | |
1117 } | |
1118 } | |
1119 receiver_maps->Add(new_receiver_map); | |
1120 return true; | |
1121 } | |
1122 | |
1123 | |
1124 static void GetReceiverMapsForStub(Handle<Code> stub, | |
1125 MapHandleList* result) { | |
1126 ASSERT(stub->is_inline_cache_stub()); | |
1127 ASSERT(stub->is_keyed_load_stub() || stub->is_keyed_store_stub()); | |
1128 switch (stub->ic_state()) { | |
1129 case MONOMORPHIC: { | |
1130 Map* map = stub->FindFirstMap(); | |
1131 if (map != NULL) { | |
1132 result->Add(Handle<Map>(map)); | |
1133 } | |
1134 break; | |
1135 } | |
1136 case POLYMORPHIC: { | |
1137 AssertNoAllocation no_allocation; | |
1138 int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); | |
1139 for (RelocIterator it(*stub, mask); !it.done(); it.next()) { | |
1140 RelocInfo* info = it.rinfo(); | |
1141 Handle<Object> object(info->target_object(), stub->GetIsolate()); | |
1142 ASSERT(object->IsMap()); | |
1143 AddOneReceiverMapIfMissing(result, Handle<Map>::cast(object)); | |
1144 } | |
1145 break; | |
1146 } | |
1147 case MEGAMORPHIC: | |
1148 break; | |
1149 case UNINITIALIZED: | |
1150 case PREMONOMORPHIC: | |
1151 case MONOMORPHIC_PROTOTYPE_FAILURE: | |
1152 case GENERIC: | |
1153 case DEBUG_STUB: | |
1154 UNREACHABLE(); | |
1155 break; | |
1156 } | |
1157 } | |
1158 | |
1159 | |
1160 Handle<Code> KeyedLoadIC::LoadElementStub(Handle<JSObject> receiver) { | 1227 Handle<Code> KeyedLoadIC::LoadElementStub(Handle<JSObject> receiver) { |
1161 State ic_state = target()->ic_state(); | 1228 State ic_state = target()->ic_state(); |
1162 | 1229 |
1163 // Don't handle megamorphic property accesses for INTERCEPTORS or CALLBACKS | 1230 // Don't handle megamorphic property accesses for INTERCEPTORS or CALLBACKS |
1164 // via megamorphic stubs, since they don't have a map in their relocation info | 1231 // via megamorphic stubs, since they don't have a map in their relocation info |
1165 // and so the stubs can't be harvested for the object needed for a map check. | 1232 // and so the stubs can't be harvested for the object needed for a map check. |
1166 if (target()->type() != Code::NORMAL) { | 1233 if (target()->type() != Code::NORMAL) { |
1167 TRACE_GENERIC_IC(isolate(), "KeyedIC", "non-NORMAL target type"); | 1234 TRACE_GENERIC_IC(isolate(), "KeyedIC", "non-NORMAL target type"); |
1168 return generic_stub(); | 1235 return generic_stub(); |
1169 } | 1236 } |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1261 ASSERT(!stub.is_null()); | 1328 ASSERT(!stub.is_null()); |
1262 set_target(*stub); | 1329 set_target(*stub); |
1263 TRACE_IC("KeyedLoadIC", key, state, target()); | 1330 TRACE_IC("KeyedLoadIC", key, state, target()); |
1264 } | 1331 } |
1265 | 1332 |
1266 | 1333 |
1267 return Runtime::GetObjectProperty(isolate(), object, key); | 1334 return Runtime::GetObjectProperty(isolate(), object, key); |
1268 } | 1335 } |
1269 | 1336 |
1270 | 1337 |
1271 Handle<Code> KeyedLoadIC::ComputeLoadMonomorphic(LookupResult* lookup, | 1338 Handle<Code> KeyedLoadIC::ComputeLoadHandler(LookupResult* lookup, |
1272 Handle<JSObject> receiver, | 1339 Handle<JSObject> receiver, |
1273 Handle<String> name) { | 1340 Handle<String> name) { |
1274 // Bail out if we didn't find a result. | 1341 // Bail out if we didn't find a result. |
1275 if (!lookup->IsProperty()) return Handle<Code>::null(); | 1342 if (!lookup->IsProperty()) return Handle<Code>::null(); |
1276 | 1343 |
1277 // Compute a monomorphic stub. | 1344 // Compute a monomorphic stub. |
1278 Handle<JSObject> holder(lookup->holder()); | 1345 Handle<JSObject> holder(lookup->holder()); |
1279 switch (lookup->type()) { | 1346 switch (lookup->type()) { |
1280 case FIELD: | 1347 case FIELD: |
1281 return isolate()->stub_cache()->ComputeKeyedLoadField( | 1348 return isolate()->stub_cache()->ComputeKeyedLoadField( |
1282 name, receiver, holder, lookup->GetFieldIndex()); | 1349 name, receiver, holder, lookup->GetFieldIndex()); |
1283 case CONSTANT_FUNCTION: { | 1350 case CONSTANT_FUNCTION: { |
(...skipping 1291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2575 #undef ADDR | 2642 #undef ADDR |
2576 }; | 2643 }; |
2577 | 2644 |
2578 | 2645 |
2579 Address IC::AddressFromUtilityId(IC::UtilityId id) { | 2646 Address IC::AddressFromUtilityId(IC::UtilityId id) { |
2580 return IC_utilities[id]; | 2647 return IC_utilities[id]; |
2581 } | 2648 } |
2582 | 2649 |
2583 | 2650 |
2584 } } // namespace v8::internal | 2651 } } // namespace v8::internal |
OLD | NEW |