| 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 975 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 986 RemovableSimulate removable) { | 986 RemovableSimulate removable) { |
| 987 ASSERT(current_block() != NULL); | 987 ASSERT(current_block() != NULL); |
| 988 ASSERT(no_side_effects_scope_count_ == 0); | 988 ASSERT(no_side_effects_scope_count_ == 0); |
| 989 current_block()->AddSimulate(id, removable); | 989 current_block()->AddSimulate(id, removable); |
| 990 } | 990 } |
| 991 | 991 |
| 992 | 992 |
| 993 HReturn* HGraphBuilder::AddReturn(HValue* value) { | 993 HReturn* HGraphBuilder::AddReturn(HValue* value) { |
| 994 HValue* context = environment()->LookupContext(); | 994 HValue* context = environment()->LookupContext(); |
| 995 int num_parameters = graph()->info()->num_parameters(); | 995 int num_parameters = graph()->info()->num_parameters(); |
| 996 HValue* params = AddInstruction(new(graph()->zone()) | 996 HValue* params = Add<HConstant>(num_parameters); |
| 997 HConstant(num_parameters)); | |
| 998 HReturn* return_instruction = new(graph()->zone()) | 997 HReturn* return_instruction = new(graph()->zone()) |
| 999 HReturn(value, context, params); | 998 HReturn(value, context, params); |
| 1000 current_block()->FinishExit(return_instruction); | 999 current_block()->FinishExit(return_instruction); |
| 1001 return return_instruction; | 1000 return return_instruction; |
| 1002 } | 1001 } |
| 1003 | 1002 |
| 1004 | 1003 |
| 1005 HBasicBlock* HGraphBuilder::CreateBasicBlock(HEnvironment* env) { | 1004 HBasicBlock* HGraphBuilder::CreateBasicBlock(HEnvironment* env) { |
| 1006 HBasicBlock* b = graph()->CreateBasicBlock(); | 1005 HBasicBlock* b = graph()->CreateBasicBlock(); |
| 1007 b->SetInitialEnvironment(env); | 1006 b->SetInitialEnvironment(env); |
| 1008 return b; | 1007 return b; |
| 1009 } | 1008 } |
| 1010 | 1009 |
| 1011 | 1010 |
| 1012 HBasicBlock* HGraphBuilder::CreateLoopHeaderBlock() { | 1011 HBasicBlock* HGraphBuilder::CreateLoopHeaderBlock() { |
| 1013 HBasicBlock* header = graph()->CreateBasicBlock(); | 1012 HBasicBlock* header = graph()->CreateBasicBlock(); |
| 1014 HEnvironment* entry_env = environment()->CopyAsLoopHeader(header); | 1013 HEnvironment* entry_env = environment()->CopyAsLoopHeader(header); |
| 1015 header->SetInitialEnvironment(entry_env); | 1014 header->SetInitialEnvironment(entry_env); |
| 1016 header->AttachLoopInformation(); | 1015 header->AttachLoopInformation(); |
| 1017 return header; | 1016 return header; |
| 1018 } | 1017 } |
| 1019 | 1018 |
| 1020 | 1019 |
| 1021 HValue* HGraphBuilder::BuildCheckHeapObject(HValue* obj) { | 1020 HValue* HGraphBuilder::BuildCheckHeapObject(HValue* obj) { |
| 1022 if (obj->type().IsHeapObject()) return obj; | 1021 if (obj->type().IsHeapObject()) return obj; |
| 1023 HCheckHeapObject* check = new(zone()) HCheckHeapObject(obj); | 1022 return Add<HCheckHeapObject>(obj); |
| 1024 AddInstruction(check); | |
| 1025 return check; | |
| 1026 } | 1023 } |
| 1027 | 1024 |
| 1028 | 1025 |
| 1029 HValue* HGraphBuilder::BuildCheckMap(HValue* obj, | 1026 HValue* HGraphBuilder::BuildCheckMap(HValue* obj, |
| 1030 Handle<Map> map) { | 1027 Handle<Map> map) { |
| 1031 HCheckMaps* check = HCheckMaps::New(obj, map, zone()); | 1028 HCheckMaps* check = HCheckMaps::New(obj, map, zone()); |
| 1032 AddInstruction(check); | 1029 AddInstruction(check); |
| 1033 return check; | 1030 return check; |
| 1034 } | 1031 } |
| 1035 | 1032 |
| 1036 | 1033 |
| 1037 HInstruction* HGraphBuilder::BuildExternalArrayElementAccess( | 1034 HInstruction* HGraphBuilder::BuildExternalArrayElementAccess( |
| 1038 HValue* external_elements, | 1035 HValue* external_elements, |
| 1039 HValue* checked_key, | 1036 HValue* checked_key, |
| 1040 HValue* val, | 1037 HValue* val, |
| 1041 HValue* dependency, | 1038 HValue* dependency, |
| 1042 ElementsKind elements_kind, | 1039 ElementsKind elements_kind, |
| 1043 bool is_store) { | 1040 bool is_store) { |
| 1044 Zone* zone = this->zone(); | 1041 Zone* zone = this->zone(); |
| 1045 if (is_store) { | 1042 if (is_store) { |
| 1046 ASSERT(val != NULL); | 1043 ASSERT(val != NULL); |
| 1047 switch (elements_kind) { | 1044 switch (elements_kind) { |
| 1048 case EXTERNAL_PIXEL_ELEMENTS: { | 1045 case EXTERNAL_PIXEL_ELEMENTS: { |
| 1049 val = AddInstruction(new(zone) HClampToUint8(val)); | 1046 val = Add<HClampToUint8>(val); |
| 1050 break; | 1047 break; |
| 1051 } | 1048 } |
| 1052 case EXTERNAL_BYTE_ELEMENTS: | 1049 case EXTERNAL_BYTE_ELEMENTS: |
| 1053 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | 1050 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
| 1054 case EXTERNAL_SHORT_ELEMENTS: | 1051 case EXTERNAL_SHORT_ELEMENTS: |
| 1055 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | 1052 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
| 1056 case EXTERNAL_INT_ELEMENTS: | 1053 case EXTERNAL_INT_ELEMENTS: |
| 1057 case EXTERNAL_UNSIGNED_INT_ELEMENTS: { | 1054 case EXTERNAL_UNSIGNED_INT_ELEMENTS: { |
| 1058 break; | 1055 break; |
| 1059 } | 1056 } |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1126 ElementsKind kind, | 1123 ElementsKind kind, |
| 1127 HValue* length, | 1124 HValue* length, |
| 1128 HValue* key, | 1125 HValue* key, |
| 1129 bool is_js_array) { | 1126 bool is_js_array) { |
| 1130 Zone* zone = this->zone(); | 1127 Zone* zone = this->zone(); |
| 1131 IfBuilder length_checker(this); | 1128 IfBuilder length_checker(this); |
| 1132 | 1129 |
| 1133 length_checker.IfCompare(length, key, Token::EQ); | 1130 length_checker.IfCompare(length, key, Token::EQ); |
| 1134 length_checker.Then(); | 1131 length_checker.Then(); |
| 1135 | 1132 |
| 1136 HValue* current_capacity = | 1133 HValue* current_capacity = Add<HFixedArrayBaseLength>(elements); |
| 1137 AddInstruction(new(zone) HFixedArrayBaseLength(elements)); | |
| 1138 | 1134 |
| 1139 IfBuilder capacity_checker(this); | 1135 IfBuilder capacity_checker(this); |
| 1140 | 1136 |
| 1141 capacity_checker.IfCompare(length, current_capacity, Token::EQ); | 1137 capacity_checker.IfCompare(length, current_capacity, Token::EQ); |
| 1142 capacity_checker.Then(); | 1138 capacity_checker.Then(); |
| 1143 | 1139 |
| 1144 HValue* context = environment()->LookupContext(); | 1140 HValue* context = environment()->LookupContext(); |
| 1145 | 1141 |
| 1146 HValue* new_capacity = | 1142 HValue* new_capacity = |
| 1147 BuildNewElementsCapacity(context, current_capacity); | 1143 BuildNewElementsCapacity(context, current_capacity); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1175 length_checker.End(); | 1171 length_checker.End(); |
| 1176 | 1172 |
| 1177 return environment()->Pop(); | 1173 return environment()->Pop(); |
| 1178 } | 1174 } |
| 1179 | 1175 |
| 1180 | 1176 |
| 1181 HValue* HGraphBuilder::BuildCopyElementsOnWrite(HValue* object, | 1177 HValue* HGraphBuilder::BuildCopyElementsOnWrite(HValue* object, |
| 1182 HValue* elements, | 1178 HValue* elements, |
| 1183 ElementsKind kind, | 1179 ElementsKind kind, |
| 1184 HValue* length) { | 1180 HValue* length) { |
| 1185 Zone* zone = this->zone(); | |
| 1186 Heap* heap = isolate()->heap(); | 1181 Heap* heap = isolate()->heap(); |
| 1187 | 1182 |
| 1188 IfBuilder cow_checker(this); | 1183 IfBuilder cow_checker(this); |
| 1189 | 1184 |
| 1190 cow_checker.IfCompareMap(elements, | 1185 cow_checker.IfCompareMap(elements, |
| 1191 Handle<Map>(heap->fixed_cow_array_map())); | 1186 Handle<Map>(heap->fixed_cow_array_map())); |
| 1192 cow_checker.Then(); | 1187 cow_checker.Then(); |
| 1193 | 1188 |
| 1194 HValue* capacity = | 1189 HValue* capacity = Add<HFixedArrayBaseLength>(elements); |
| 1195 AddInstruction(new(zone) HFixedArrayBaseLength(elements)); | |
| 1196 | 1190 |
| 1197 HValue* new_elements = BuildGrowElementsCapacity(object, elements, | 1191 HValue* new_elements = BuildGrowElementsCapacity(object, elements, |
| 1198 kind, length, capacity); | 1192 kind, length, capacity); |
| 1199 | 1193 |
| 1200 environment()->Push(new_elements); | 1194 environment()->Push(new_elements); |
| 1201 | 1195 |
| 1202 cow_checker.Else(); | 1196 cow_checker.Else(); |
| 1203 | 1197 |
| 1204 environment()->Push(elements); | 1198 environment()->Push(elements); |
| 1205 | 1199 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1242 elements, isolate()->factory()->fixed_array_map(), zone); | 1236 elements, isolate()->factory()->fixed_array_map(), zone); |
| 1243 check_cow_map->ClearGVNFlag(kDependsOnElementsKind); | 1237 check_cow_map->ClearGVNFlag(kDependsOnElementsKind); |
| 1244 AddInstruction(check_cow_map); | 1238 AddInstruction(check_cow_map); |
| 1245 } | 1239 } |
| 1246 HInstruction* length = NULL; | 1240 HInstruction* length = NULL; |
| 1247 if (is_js_array) { | 1241 if (is_js_array) { |
| 1248 length = AddLoad(object, HObjectAccess::ForArrayLength(), mapcheck, | 1242 length = AddLoad(object, HObjectAccess::ForArrayLength(), mapcheck, |
| 1249 Representation::Smi()); | 1243 Representation::Smi()); |
| 1250 length->set_type(HType::Smi()); | 1244 length->set_type(HType::Smi()); |
| 1251 } else { | 1245 } else { |
| 1252 length = AddInstruction(new(zone) HFixedArrayBaseLength(elements)); | 1246 length = Add<HFixedArrayBaseLength>(elements); |
| 1253 } | 1247 } |
| 1254 HValue* checked_key = NULL; | 1248 HValue* checked_key = NULL; |
| 1255 if (IsExternalArrayElementsKind(elements_kind)) { | 1249 if (IsExternalArrayElementsKind(elements_kind)) { |
| 1256 if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) { | 1250 if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) { |
| 1257 NoObservableSideEffectsScope no_effects(this); | 1251 NoObservableSideEffectsScope no_effects(this); |
| 1258 HLoadExternalArrayPointer* external_elements = | 1252 HLoadExternalArrayPointer* external_elements = |
| 1259 new(zone) HLoadExternalArrayPointer(elements); | 1253 Add<HLoadExternalArrayPointer>(elements); |
| 1260 AddInstruction(external_elements); | |
| 1261 IfBuilder length_checker(this); | 1254 IfBuilder length_checker(this); |
| 1262 length_checker.IfCompare(key, length, Token::LT); | 1255 length_checker.IfCompare(key, length, Token::LT); |
| 1263 length_checker.Then(); | 1256 length_checker.Then(); |
| 1264 IfBuilder negative_checker(this); | 1257 IfBuilder negative_checker(this); |
| 1265 HValue* bounds_check = negative_checker.IfCompare( | 1258 HValue* bounds_check = negative_checker.IfCompare( |
| 1266 key, graph()->GetConstant0(), Token::GTE); | 1259 key, graph()->GetConstant0(), Token::GTE); |
| 1267 negative_checker.Then(); | 1260 negative_checker.Then(); |
| 1268 HInstruction* result = BuildExternalArrayElementAccess( | 1261 HInstruction* result = BuildExternalArrayElementAccess( |
| 1269 external_elements, key, val, bounds_check, | 1262 external_elements, key, val, bounds_check, |
| 1270 elements_kind, is_store); | 1263 elements_kind, is_store); |
| 1271 AddInstruction(result); | 1264 AddInstruction(result); |
| 1272 negative_checker.ElseDeopt(); | 1265 negative_checker.ElseDeopt(); |
| 1273 length_checker.End(); | 1266 length_checker.End(); |
| 1274 return result; | 1267 return result; |
| 1275 } else { | 1268 } else { |
| 1276 ASSERT(store_mode == STANDARD_STORE); | 1269 ASSERT(store_mode == STANDARD_STORE); |
| 1277 checked_key = Add<HBoundsCheck>(key, length); | 1270 checked_key = Add<HBoundsCheck>(key, length); |
| 1278 HLoadExternalArrayPointer* external_elements = | 1271 HLoadExternalArrayPointer* external_elements = |
| 1279 new(zone) HLoadExternalArrayPointer(elements); | 1272 Add<HLoadExternalArrayPointer>(elements); |
| 1280 AddInstruction(external_elements); | |
| 1281 return AddInstruction(BuildExternalArrayElementAccess( | 1273 return AddInstruction(BuildExternalArrayElementAccess( |
| 1282 external_elements, checked_key, val, mapcheck, | 1274 external_elements, checked_key, val, mapcheck, |
| 1283 elements_kind, is_store)); | 1275 elements_kind, is_store)); |
| 1284 } | 1276 } |
| 1285 } | 1277 } |
| 1286 ASSERT(fast_smi_only_elements || | 1278 ASSERT(fast_smi_only_elements || |
| 1287 fast_elements || | 1279 fast_elements || |
| 1288 IsFastDoubleElementsKind(elements_kind)); | 1280 IsFastDoubleElementsKind(elements_kind)); |
| 1289 | 1281 |
| 1290 // In case val is stored into a fast smi array, assure that the value is a smi | 1282 // In case val is stored into a fast smi array, assure that the value is a smi |
| 1291 // before manipulating the backing store. Otherwise the actual store may | 1283 // before manipulating the backing store. Otherwise the actual store may |
| 1292 // deopt, leaving the backing store in an invalid state. | 1284 // deopt, leaving the backing store in an invalid state. |
| 1293 if (is_store && IsFastSmiElementsKind(elements_kind) && | 1285 if (is_store && IsFastSmiElementsKind(elements_kind) && |
| 1294 !val->type().IsSmi()) { | 1286 !val->type().IsSmi()) { |
| 1295 val = AddInstruction(new(zone) HForceRepresentation( | 1287 val = Add<HForceRepresentation>(val, Representation::Smi()); |
| 1296 val, Representation::Smi())); | |
| 1297 } | 1288 } |
| 1298 | 1289 |
| 1299 if (IsGrowStoreMode(store_mode)) { | 1290 if (IsGrowStoreMode(store_mode)) { |
| 1300 NoObservableSideEffectsScope no_effects(this); | 1291 NoObservableSideEffectsScope no_effects(this); |
| 1301 elements = BuildCheckForCapacityGrow(object, elements, elements_kind, | 1292 elements = BuildCheckForCapacityGrow(object, elements, elements_kind, |
| 1302 length, key, is_js_array); | 1293 length, key, is_js_array); |
| 1303 checked_key = key; | 1294 checked_key = key; |
| 1304 } else { | 1295 } else { |
| 1305 checked_key = Add<HBoundsCheck>(key, length); | 1296 checked_key = Add<HBoundsCheck>(key, length); |
| 1306 | 1297 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1324 } | 1315 } |
| 1325 | 1316 |
| 1326 | 1317 |
| 1327 HValue* HGraphBuilder::BuildAllocateElements(HValue* context, | 1318 HValue* HGraphBuilder::BuildAllocateElements(HValue* context, |
| 1328 ElementsKind kind, | 1319 ElementsKind kind, |
| 1329 HValue* capacity) { | 1320 HValue* capacity) { |
| 1330 Zone* zone = this->zone(); | 1321 Zone* zone = this->zone(); |
| 1331 | 1322 |
| 1332 int elements_size = IsFastDoubleElementsKind(kind) | 1323 int elements_size = IsFastDoubleElementsKind(kind) |
| 1333 ? kDoubleSize : kPointerSize; | 1324 ? kDoubleSize : kPointerSize; |
| 1334 HConstant* elements_size_value = new(zone) HConstant(elements_size); | 1325 HConstant* elements_size_value = Add<HConstant>(elements_size); |
| 1335 AddInstruction(elements_size_value); | |
| 1336 HValue* mul = AddInstruction( | 1326 HValue* mul = AddInstruction( |
| 1337 HMul::New(zone, context, capacity, elements_size_value)); | 1327 HMul::New(zone, context, capacity, elements_size_value)); |
| 1338 mul->ClearFlag(HValue::kCanOverflow); | 1328 mul->ClearFlag(HValue::kCanOverflow); |
| 1339 | 1329 |
| 1340 HConstant* header_size = new(zone) HConstant(FixedArray::kHeaderSize); | 1330 HConstant* header_size = Add<HConstant>(FixedArray::kHeaderSize); |
| 1341 AddInstruction(header_size); | |
| 1342 HValue* total_size = AddInstruction( | 1331 HValue* total_size = AddInstruction( |
| 1343 HAdd::New(zone, context, mul, header_size)); | 1332 HAdd::New(zone, context, mul, header_size)); |
| 1344 total_size->ClearFlag(HValue::kCanOverflow); | 1333 total_size->ClearFlag(HValue::kCanOverflow); |
| 1345 | 1334 |
| 1346 HAllocate::Flags flags = HAllocate::DefaultFlags(kind); | 1335 HAllocate::Flags flags = HAllocate::DefaultFlags(kind); |
| 1347 if (isolate()->heap()->ShouldGloballyPretenure()) { | 1336 if (isolate()->heap()->ShouldGloballyPretenure()) { |
| 1348 // TODO(hpayer): When pretenuring can be internalized, flags can become | 1337 // TODO(hpayer): When pretenuring can be internalized, flags can become |
| 1349 // private to HAllocate. | 1338 // private to HAllocate. |
| 1350 if (IsFastDoubleElementsKind(kind)) { | 1339 if (IsFastDoubleElementsKind(kind)) { |
| 1351 flags = static_cast<HAllocate::Flags>( | 1340 flags = static_cast<HAllocate::Flags>( |
| 1352 flags | HAllocate::CAN_ALLOCATE_IN_OLD_DATA_SPACE); | 1341 flags | HAllocate::CAN_ALLOCATE_IN_OLD_DATA_SPACE); |
| 1353 } else { | 1342 } else { |
| 1354 flags = static_cast<HAllocate::Flags>( | 1343 flags = static_cast<HAllocate::Flags>( |
| 1355 flags | HAllocate::CAN_ALLOCATE_IN_OLD_POINTER_SPACE); | 1344 flags | HAllocate::CAN_ALLOCATE_IN_OLD_POINTER_SPACE); |
| 1356 } | 1345 } |
| 1357 } | 1346 } |
| 1358 | 1347 |
| 1359 HValue* elements = | 1348 return Add<HAllocate>(context, total_size, HType::JSArray(), flags); |
| 1360 AddInstruction(new(zone) HAllocate(context, total_size, | |
| 1361 HType::JSArray(), flags)); | |
| 1362 return elements; | |
| 1363 } | 1349 } |
| 1364 | 1350 |
| 1365 | 1351 |
| 1366 void HGraphBuilder::BuildInitializeElementsHeader(HValue* elements, | 1352 void HGraphBuilder::BuildInitializeElementsHeader(HValue* elements, |
| 1367 ElementsKind kind, | 1353 ElementsKind kind, |
| 1368 HValue* capacity) { | 1354 HValue* capacity) { |
| 1369 Factory* factory = isolate()->factory(); | 1355 Factory* factory = isolate()->factory(); |
| 1370 Handle<Map> map = IsFastDoubleElementsKind(kind) | 1356 Handle<Map> map = IsFastDoubleElementsKind(kind) |
| 1371 ? factory->fixed_double_array_map() | 1357 ? factory->fixed_double_array_map() |
| 1372 : factory->fixed_array_map(); | 1358 : factory->fixed_array_map(); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1391 | 1377 |
| 1392 HInnerAllocatedObject* HGraphBuilder::BuildJSArrayHeader(HValue* array, | 1378 HInnerAllocatedObject* HGraphBuilder::BuildJSArrayHeader(HValue* array, |
| 1393 HValue* array_map, | 1379 HValue* array_map, |
| 1394 AllocationSiteMode mode, | 1380 AllocationSiteMode mode, |
| 1395 HValue* allocation_site_payload, | 1381 HValue* allocation_site_payload, |
| 1396 HValue* length_field) { | 1382 HValue* length_field) { |
| 1397 | 1383 |
| 1398 AddStore(array, HObjectAccess::ForMap(), array_map); | 1384 AddStore(array, HObjectAccess::ForMap(), array_map); |
| 1399 | 1385 |
| 1400 HConstant* empty_fixed_array = | 1386 HConstant* empty_fixed_array = |
| 1401 new(zone()) HConstant(isolate()->factory()->empty_fixed_array()); | 1387 Add<HConstant>(isolate()->factory()->empty_fixed_array()); |
| 1402 AddInstruction(empty_fixed_array); | |
| 1403 | 1388 |
| 1404 HObjectAccess access = HObjectAccess::ForPropertiesPointer(); | 1389 HObjectAccess access = HObjectAccess::ForPropertiesPointer(); |
| 1405 AddStore(array, access, empty_fixed_array); | 1390 AddStore(array, access, empty_fixed_array); |
| 1406 AddStore(array, HObjectAccess::ForArrayLength(), length_field); | 1391 AddStore(array, HObjectAccess::ForArrayLength(), length_field); |
| 1407 | 1392 |
| 1408 if (mode == TRACK_ALLOCATION_SITE) { | 1393 if (mode == TRACK_ALLOCATION_SITE) { |
| 1409 BuildCreateAllocationSiteInfo(array, | 1394 BuildCreateAllocationSiteInfo(array, |
| 1410 JSArray::kSize, | 1395 JSArray::kSize, |
| 1411 allocation_site_payload); | 1396 allocation_site_payload); |
| 1412 } | 1397 } |
| 1413 | 1398 |
| 1414 int elements_location = JSArray::kSize; | 1399 int elements_location = JSArray::kSize; |
| 1415 if (mode == TRACK_ALLOCATION_SITE) { | 1400 if (mode == TRACK_ALLOCATION_SITE) { |
| 1416 elements_location += AllocationSiteInfo::kSize; | 1401 elements_location += AllocationSiteInfo::kSize; |
| 1417 } | 1402 } |
| 1418 | 1403 |
| 1419 HInnerAllocatedObject* elements = new(zone()) HInnerAllocatedObject( | 1404 HInnerAllocatedObject* elements = |
| 1420 array, elements_location); | 1405 Add<HInnerAllocatedObject>(array, elements_location); |
| 1421 AddInstruction(elements); | |
| 1422 | |
| 1423 AddStore(array, HObjectAccess::ForElementsPointer(), elements); | 1406 AddStore(array, HObjectAccess::ForElementsPointer(), elements); |
| 1424 return elements; | 1407 return elements; |
| 1425 } | 1408 } |
| 1426 | 1409 |
| 1427 | 1410 |
| 1428 HLoadNamedField* HGraphBuilder::AddLoadElements(HValue* object, | 1411 HLoadNamedField* HGraphBuilder::AddLoadElements(HValue* object, |
| 1429 HValue* typecheck) { | 1412 HValue* typecheck) { |
| 1430 return AddLoad(object, HObjectAccess::ForElementsPointer(), typecheck); | 1413 return AddLoad(object, HObjectAccess::ForElementsPointer(), typecheck); |
| 1431 } | 1414 } |
| 1432 | 1415 |
| 1433 | 1416 |
| 1434 HValue* HGraphBuilder::BuildNewElementsCapacity(HValue* context, | 1417 HValue* HGraphBuilder::BuildNewElementsCapacity(HValue* context, |
| 1435 HValue* old_capacity) { | 1418 HValue* old_capacity) { |
| 1436 Zone* zone = this->zone(); | 1419 Zone* zone = this->zone(); |
| 1437 HValue* half_old_capacity = | 1420 HValue* half_old_capacity = |
| 1438 AddInstruction(HShr::New(zone, context, old_capacity, | 1421 AddInstruction(HShr::New(zone, context, old_capacity, |
| 1439 graph_->GetConstant1())); | 1422 graph_->GetConstant1())); |
| 1440 half_old_capacity->ClearFlag(HValue::kCanOverflow); | 1423 half_old_capacity->ClearFlag(HValue::kCanOverflow); |
| 1441 | 1424 |
| 1442 HValue* new_capacity = AddInstruction( | 1425 HValue* new_capacity = AddInstruction( |
| 1443 HAdd::New(zone, context, half_old_capacity, old_capacity)); | 1426 HAdd::New(zone, context, half_old_capacity, old_capacity)); |
| 1444 new_capacity->ClearFlag(HValue::kCanOverflow); | 1427 new_capacity->ClearFlag(HValue::kCanOverflow); |
| 1445 | 1428 |
| 1446 HValue* min_growth = AddInstruction(new(zone) HConstant(16)); | 1429 HValue* min_growth = Add<HConstant>(16); |
| 1447 | 1430 |
| 1448 new_capacity = AddInstruction( | 1431 new_capacity = AddInstruction( |
| 1449 HAdd::New(zone, context, new_capacity, min_growth)); | 1432 HAdd::New(zone, context, new_capacity, min_growth)); |
| 1450 new_capacity->ClearFlag(HValue::kCanOverflow); | 1433 new_capacity->ClearFlag(HValue::kCanOverflow); |
| 1451 | 1434 |
| 1452 return new_capacity; | 1435 return new_capacity; |
| 1453 } | 1436 } |
| 1454 | 1437 |
| 1455 | 1438 |
| 1456 void HGraphBuilder::BuildNewSpaceArrayCheck(HValue* length, ElementsKind kind) { | 1439 void HGraphBuilder::BuildNewSpaceArrayCheck(HValue* length, ElementsKind kind) { |
| 1457 Zone* zone = this->zone(); | |
| 1458 Heap* heap = isolate()->heap(); | 1440 Heap* heap = isolate()->heap(); |
| 1459 int element_size = IsFastDoubleElementsKind(kind) ? kDoubleSize | 1441 int element_size = IsFastDoubleElementsKind(kind) ? kDoubleSize |
| 1460 : kPointerSize; | 1442 : kPointerSize; |
| 1461 int max_size = heap->MaxRegularSpaceAllocationSize() / element_size; | 1443 int max_size = heap->MaxRegularSpaceAllocationSize() / element_size; |
| 1462 max_size -= JSArray::kSize / element_size; | 1444 max_size -= JSArray::kSize / element_size; |
| 1463 HConstant* max_size_constant = new(zone) HConstant(max_size); | 1445 HConstant* max_size_constant = Add<HConstant>(max_size); |
| 1464 AddInstruction(max_size_constant); | |
| 1465 // Since we're forcing Integer32 representation for this HBoundsCheck, | 1446 // Since we're forcing Integer32 representation for this HBoundsCheck, |
| 1466 // there's no need to Smi-check the index. | 1447 // there's no need to Smi-check the index. |
| 1467 AddInstruction(new(zone) HBoundsCheck(length, max_size_constant)); | 1448 Add<HBoundsCheck>(length, max_size_constant); |
| 1468 } | 1449 } |
| 1469 | 1450 |
| 1470 | 1451 |
| 1471 HValue* HGraphBuilder::BuildGrowElementsCapacity(HValue* object, | 1452 HValue* HGraphBuilder::BuildGrowElementsCapacity(HValue* object, |
| 1472 HValue* elements, | 1453 HValue* elements, |
| 1473 ElementsKind kind, | 1454 ElementsKind kind, |
| 1474 HValue* length, | 1455 HValue* length, |
| 1475 HValue* new_capacity) { | 1456 HValue* new_capacity) { |
| 1476 HValue* context = environment()->LookupContext(); | 1457 HValue* context = environment()->LookupContext(); |
| 1477 | 1458 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1493 void HGraphBuilder::BuildFillElementsWithHole(HValue* context, | 1474 void HGraphBuilder::BuildFillElementsWithHole(HValue* context, |
| 1494 HValue* elements, | 1475 HValue* elements, |
| 1495 ElementsKind elements_kind, | 1476 ElementsKind elements_kind, |
| 1496 HValue* from, | 1477 HValue* from, |
| 1497 HValue* to) { | 1478 HValue* to) { |
| 1498 // Fast elements kinds need to be initialized in case statements below cause | 1479 // Fast elements kinds need to be initialized in case statements below cause |
| 1499 // a garbage collection. | 1480 // a garbage collection. |
| 1500 Factory* factory = isolate()->factory(); | 1481 Factory* factory = isolate()->factory(); |
| 1501 | 1482 |
| 1502 double nan_double = FixedDoubleArray::hole_nan_as_double(); | 1483 double nan_double = FixedDoubleArray::hole_nan_as_double(); |
| 1503 Zone* zone = this->zone(); | |
| 1504 HValue* hole = IsFastSmiOrObjectElementsKind(elements_kind) | 1484 HValue* hole = IsFastSmiOrObjectElementsKind(elements_kind) |
| 1505 ? AddInstruction(new(zone) HConstant(factory->the_hole_value())) | 1485 ? Add<HConstant>(factory->the_hole_value()) |
| 1506 : AddInstruction(new(zone) HConstant(nan_double)); | 1486 : Add<HConstant>(nan_double); |
| 1507 | 1487 |
| 1508 // Special loop unfolding case | 1488 // Special loop unfolding case |
| 1509 static const int kLoopUnfoldLimit = 4; | 1489 static const int kLoopUnfoldLimit = 4; |
| 1510 bool unfold_loop = false; | 1490 bool unfold_loop = false; |
| 1511 int initial_capacity = JSArray::kPreallocatedArrayElements; | 1491 int initial_capacity = JSArray::kPreallocatedArrayElements; |
| 1512 if (from->IsConstant() && to->IsConstant() && | 1492 if (from->IsConstant() && to->IsConstant() && |
| 1513 initial_capacity <= kLoopUnfoldLimit) { | 1493 initial_capacity <= kLoopUnfoldLimit) { |
| 1514 HConstant* constant_from = HConstant::cast(from); | 1494 HConstant* constant_from = HConstant::cast(from); |
| 1515 HConstant* constant_to = HConstant::cast(to); | 1495 HConstant* constant_to = HConstant::cast(to); |
| 1516 | 1496 |
| 1517 if (constant_from->HasInteger32Value() && | 1497 if (constant_from->HasInteger32Value() && |
| 1518 constant_from->Integer32Value() == 0 && | 1498 constant_from->Integer32Value() == 0 && |
| 1519 constant_to->HasInteger32Value() && | 1499 constant_to->HasInteger32Value() && |
| 1520 constant_to->Integer32Value() == initial_capacity) { | 1500 constant_to->Integer32Value() == initial_capacity) { |
| 1521 unfold_loop = true; | 1501 unfold_loop = true; |
| 1522 } | 1502 } |
| 1523 } | 1503 } |
| 1524 | 1504 |
| 1525 // Since we're about to store a hole value, the store instruction below must | 1505 // Since we're about to store a hole value, the store instruction below must |
| 1526 // assume an elements kind that supports heap object values. | 1506 // assume an elements kind that supports heap object values. |
| 1527 if (IsFastSmiOrObjectElementsKind(elements_kind)) { | 1507 if (IsFastSmiOrObjectElementsKind(elements_kind)) { |
| 1528 elements_kind = FAST_HOLEY_ELEMENTS; | 1508 elements_kind = FAST_HOLEY_ELEMENTS; |
| 1529 } | 1509 } |
| 1530 | 1510 |
| 1531 if (unfold_loop) { | 1511 if (unfold_loop) { |
| 1532 for (int i = 0; i < initial_capacity; i++) { | 1512 for (int i = 0; i < initial_capacity; i++) { |
| 1533 HInstruction* key = AddInstruction(new(zone) HConstant(i)); | 1513 HInstruction* key = Add<HConstant>(i); |
| 1534 AddInstruction(new(zone) HStoreKeyed(elements, key, hole, elements_kind)); | 1514 Add<HStoreKeyed>(elements, key, hole, elements_kind); |
| 1535 } | 1515 } |
| 1536 } else { | 1516 } else { |
| 1537 LoopBuilder builder(this, context, LoopBuilder::kPostIncrement); | 1517 LoopBuilder builder(this, context, LoopBuilder::kPostIncrement); |
| 1538 | 1518 |
| 1539 HValue* key = builder.BeginBody(from, to, Token::LT); | 1519 HValue* key = builder.BeginBody(from, to, Token::LT); |
| 1540 | 1520 |
| 1541 AddInstruction(new(zone) HStoreKeyed(elements, key, hole, elements_kind)); | 1521 Add<HStoreKeyed>(elements, key, hole, elements_kind); |
| 1542 | 1522 |
| 1543 builder.EndBody(); | 1523 builder.EndBody(); |
| 1544 } | 1524 } |
| 1545 } | 1525 } |
| 1546 | 1526 |
| 1547 | 1527 |
| 1548 void HGraphBuilder::BuildCopyElements(HValue* context, | 1528 void HGraphBuilder::BuildCopyElements(HValue* context, |
| 1549 HValue* from_elements, | 1529 HValue* from_elements, |
| 1550 ElementsKind from_elements_kind, | 1530 ElementsKind from_elements_kind, |
| 1551 HValue* to_elements, | 1531 HValue* to_elements, |
| 1552 ElementsKind to_elements_kind, | 1532 ElementsKind to_elements_kind, |
| 1553 HValue* length, | 1533 HValue* length, |
| 1554 HValue* capacity) { | 1534 HValue* capacity) { |
| 1555 bool pre_fill_with_holes = | 1535 bool pre_fill_with_holes = |
| 1556 IsFastDoubleElementsKind(from_elements_kind) && | 1536 IsFastDoubleElementsKind(from_elements_kind) && |
| 1557 IsFastObjectElementsKind(to_elements_kind); | 1537 IsFastObjectElementsKind(to_elements_kind); |
| 1558 | 1538 |
| 1559 if (pre_fill_with_holes) { | 1539 if (pre_fill_with_holes) { |
| 1560 // If the copy might trigger a GC, make sure that the FixedArray is | 1540 // If the copy might trigger a GC, make sure that the FixedArray is |
| 1561 // pre-initialized with holes to make sure that it's always in a consistent | 1541 // pre-initialized with holes to make sure that it's always in a consistent |
| 1562 // state. | 1542 // state. |
| 1563 BuildFillElementsWithHole(context, to_elements, to_elements_kind, | 1543 BuildFillElementsWithHole(context, to_elements, to_elements_kind, |
| 1564 graph()->GetConstant0(), capacity); | 1544 graph()->GetConstant0(), capacity); |
| 1565 } | 1545 } |
| 1566 | 1546 |
| 1567 LoopBuilder builder(this, context, LoopBuilder::kPostIncrement); | 1547 LoopBuilder builder(this, context, LoopBuilder::kPostIncrement); |
| 1568 | 1548 |
| 1569 HValue* key = builder.BeginBody(graph()->GetConstant0(), length, Token::LT); | 1549 HValue* key = builder.BeginBody(graph()->GetConstant0(), length, Token::LT); |
| 1570 | 1550 |
| 1571 HValue* element = | 1551 HValue* element = Add<HLoadKeyed>(from_elements, key, |
| 1572 AddInstruction(new(zone()) HLoadKeyed(from_elements, key, NULL, | 1552 static_cast<HValue*>(NULL), |
| 1573 from_elements_kind, | 1553 from_elements_kind, |
| 1574 ALLOW_RETURN_HOLE)); | 1554 ALLOW_RETURN_HOLE); |
| 1575 | 1555 |
| 1576 ElementsKind holey_kind = IsFastSmiElementsKind(to_elements_kind) | 1556 ElementsKind holey_kind = IsFastSmiElementsKind(to_elements_kind) |
| 1577 ? FAST_HOLEY_ELEMENTS : to_elements_kind; | 1557 ? FAST_HOLEY_ELEMENTS : to_elements_kind; |
| 1578 HInstruction* holey_store = AddInstruction( | 1558 HInstruction* holey_store = Add<HStoreKeyed>(to_elements, key, |
| 1579 new(zone()) HStoreKeyed(to_elements, key, element, holey_kind)); | 1559 element, holey_kind); |
| 1580 // Allow NaN hole values to converted to their tagged counterparts. | 1560 // Allow NaN hole values to converted to their tagged counterparts. |
| 1581 if (IsFastHoleyElementsKind(to_elements_kind)) { | 1561 if (IsFastHoleyElementsKind(to_elements_kind)) { |
| 1582 holey_store->SetFlag(HValue::kAllowUndefinedAsNaN); | 1562 holey_store->SetFlag(HValue::kAllowUndefinedAsNaN); |
| 1583 } | 1563 } |
| 1584 | 1564 |
| 1585 builder.EndBody(); | 1565 builder.EndBody(); |
| 1586 | 1566 |
| 1587 if (!pre_fill_with_holes && length != capacity) { | 1567 if (!pre_fill_with_holes && length != capacity) { |
| 1588 // Fill unused capacity with the hole. | 1568 // Fill unused capacity with the hole. |
| 1589 BuildFillElementsWithHole(context, to_elements, to_elements_kind, | 1569 BuildFillElementsWithHole(context, to_elements, to_elements_kind, |
| 1590 key, capacity); | 1570 key, capacity); |
| 1591 } | 1571 } |
| 1592 } | 1572 } |
| 1593 | 1573 |
| 1594 | 1574 |
| 1595 HValue* HGraphBuilder::BuildCloneShallowArray(HContext* context, | 1575 HValue* HGraphBuilder::BuildCloneShallowArray(HContext* context, |
| 1596 HValue* boilerplate, | 1576 HValue* boilerplate, |
| 1597 AllocationSiteMode mode, | 1577 AllocationSiteMode mode, |
| 1598 ElementsKind kind, | 1578 ElementsKind kind, |
| 1599 int length) { | 1579 int length) { |
| 1600 Zone* zone = this->zone(); | |
| 1601 | |
| 1602 NoObservableSideEffectsScope no_effects(this); | 1580 NoObservableSideEffectsScope no_effects(this); |
| 1603 | 1581 |
| 1604 // All sizes here are multiples of kPointerSize. | 1582 // All sizes here are multiples of kPointerSize. |
| 1605 int size = JSArray::kSize; | 1583 int size = JSArray::kSize; |
| 1606 if (mode == TRACK_ALLOCATION_SITE) { | 1584 if (mode == TRACK_ALLOCATION_SITE) { |
| 1607 size += AllocationSiteInfo::kSize; | 1585 size += AllocationSiteInfo::kSize; |
| 1608 } | 1586 } |
| 1609 int elems_offset = size; | 1587 int elems_offset = size; |
| 1610 if (length > 0) { | 1588 if (length > 0) { |
| 1611 size += IsFastDoubleElementsKind(kind) | 1589 size += IsFastDoubleElementsKind(kind) |
| 1612 ? FixedDoubleArray::SizeFor(length) | 1590 ? FixedDoubleArray::SizeFor(length) |
| 1613 : FixedArray::SizeFor(length); | 1591 : FixedArray::SizeFor(length); |
| 1614 } | 1592 } |
| 1615 | 1593 |
| 1616 HAllocate::Flags allocate_flags = HAllocate::DefaultFlags(kind); | 1594 HAllocate::Flags allocate_flags = HAllocate::DefaultFlags(kind); |
| 1617 // Allocate both the JS array and the elements array in one big | 1595 // Allocate both the JS array and the elements array in one big |
| 1618 // allocation. This avoids multiple limit checks. | 1596 // allocation. This avoids multiple limit checks. |
| 1619 HValue* size_in_bytes = AddInstruction(new(zone) HConstant(size)); | 1597 HValue* size_in_bytes = Add<HConstant>(size); |
| 1620 HInstruction* object = | 1598 HInstruction* object = Add<HAllocate>(context, |
| 1621 AddInstruction(new(zone) HAllocate(context, | 1599 size_in_bytes, |
| 1622 size_in_bytes, | 1600 HType::JSObject(), |
| 1623 HType::JSObject(), | 1601 allocate_flags); |
| 1624 allocate_flags)); | |
| 1625 | 1602 |
| 1626 // Copy the JS array part. | 1603 // Copy the JS array part. |
| 1627 for (int i = 0; i < JSArray::kSize; i += kPointerSize) { | 1604 for (int i = 0; i < JSArray::kSize; i += kPointerSize) { |
| 1628 if ((i != JSArray::kElementsOffset) || (length == 0)) { | 1605 if ((i != JSArray::kElementsOffset) || (length == 0)) { |
| 1629 HObjectAccess access = HObjectAccess::ForJSArrayOffset(i); | 1606 HObjectAccess access = HObjectAccess::ForJSArrayOffset(i); |
| 1630 AddStore(object, access, AddLoad(boilerplate, access)); | 1607 AddStore(object, access, AddLoad(boilerplate, access)); |
| 1631 } | 1608 } |
| 1632 } | 1609 } |
| 1633 | 1610 |
| 1634 // Create an allocation site info if requested. | 1611 // Create an allocation site info if requested. |
| 1635 if (mode == TRACK_ALLOCATION_SITE) { | 1612 if (mode == TRACK_ALLOCATION_SITE) { |
| 1636 BuildCreateAllocationSiteInfo(object, JSArray::kSize, boilerplate); | 1613 BuildCreateAllocationSiteInfo(object, JSArray::kSize, boilerplate); |
| 1637 } | 1614 } |
| 1638 | 1615 |
| 1639 if (length > 0) { | 1616 if (length > 0) { |
| 1640 // Get hold of the elements array of the boilerplate and setup the | 1617 // Get hold of the elements array of the boilerplate and setup the |
| 1641 // elements pointer in the resulting object. | 1618 // elements pointer in the resulting object. |
| 1642 HValue* boilerplate_elements = AddLoadElements(boilerplate); | 1619 HValue* boilerplate_elements = AddLoadElements(boilerplate); |
| 1643 HValue* object_elements = | 1620 HValue* object_elements = Add<HInnerAllocatedObject>(object, elems_offset); |
| 1644 AddInstruction(new(zone) HInnerAllocatedObject(object, elems_offset)); | |
| 1645 AddStore(object, HObjectAccess::ForElementsPointer(), object_elements); | 1621 AddStore(object, HObjectAccess::ForElementsPointer(), object_elements); |
| 1646 | 1622 |
| 1647 // Copy the elements array header. | 1623 // Copy the elements array header. |
| 1648 for (int i = 0; i < FixedArrayBase::kHeaderSize; i += kPointerSize) { | 1624 for (int i = 0; i < FixedArrayBase::kHeaderSize; i += kPointerSize) { |
| 1649 HObjectAccess access = HObjectAccess::ForFixedArrayHeader(i); | 1625 HObjectAccess access = HObjectAccess::ForFixedArrayHeader(i); |
| 1650 AddStore(object_elements, access, AddLoad(boilerplate_elements, access)); | 1626 AddStore(object_elements, access, AddLoad(boilerplate_elements, access)); |
| 1651 } | 1627 } |
| 1652 | 1628 |
| 1653 // Copy the elements array contents. | 1629 // Copy the elements array contents. |
| 1654 // TODO(mstarzinger): Teach HGraphBuilder::BuildCopyElements to unfold | 1630 // TODO(mstarzinger): Teach HGraphBuilder::BuildCopyElements to unfold |
| 1655 // copying loops with constant length up to a given boundary and use this | 1631 // copying loops with constant length up to a given boundary and use this |
| 1656 // helper here instead. | 1632 // helper here instead. |
| 1657 for (int i = 0; i < length; i++) { | 1633 for (int i = 0; i < length; i++) { |
| 1658 HValue* key_constant = AddInstruction(new(zone) HConstant(i)); | 1634 HValue* key_constant = Add<HConstant>(i); |
| 1659 HInstruction* value = | 1635 HInstruction* value = Add<HLoadKeyed>(boilerplate_elements, key_constant, |
| 1660 AddInstruction(new(zone) HLoadKeyed(boilerplate_elements, | 1636 static_cast<HValue*>(NULL), kind); |
| 1661 key_constant, | 1637 Add<HStoreKeyed>(object_elements, key_constant, value, kind); |
| 1662 NULL, | |
| 1663 kind)); | |
| 1664 AddInstruction(new(zone) HStoreKeyed(object_elements, | |
| 1665 key_constant, | |
| 1666 value, | |
| 1667 kind)); | |
| 1668 } | 1638 } |
| 1669 } | 1639 } |
| 1670 | 1640 |
| 1671 return object; | 1641 return object; |
| 1672 } | 1642 } |
| 1673 | 1643 |
| 1674 | 1644 |
| 1675 void HGraphBuilder::BuildCompareNil( | 1645 void HGraphBuilder::BuildCompareNil( |
| 1676 HValue* value, | 1646 HValue* value, |
| 1677 Handle<Type> type, | 1647 Handle<Type> type, |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1708 } | 1678 } |
| 1709 } | 1679 } |
| 1710 | 1680 |
| 1711 if_nil.CaptureContinuation(continuation); | 1681 if_nil.CaptureContinuation(continuation); |
| 1712 } | 1682 } |
| 1713 | 1683 |
| 1714 | 1684 |
| 1715 HValue* HGraphBuilder::BuildCreateAllocationSiteInfo(HValue* previous_object, | 1685 HValue* HGraphBuilder::BuildCreateAllocationSiteInfo(HValue* previous_object, |
| 1716 int previous_object_size, | 1686 int previous_object_size, |
| 1717 HValue* payload) { | 1687 HValue* payload) { |
| 1718 HInnerAllocatedObject* alloc_site = new(zone()) | 1688 HInnerAllocatedObject* alloc_site = Add<HInnerAllocatedObject>( |
| 1719 HInnerAllocatedObject(previous_object, previous_object_size); | 1689 previous_object, previous_object_size); |
| 1720 AddInstruction(alloc_site); | |
| 1721 Handle<Map> alloc_site_map(isolate()->heap()->allocation_site_info_map()); | 1690 Handle<Map> alloc_site_map(isolate()->heap()->allocation_site_info_map()); |
| 1722 AddStoreMapConstant(alloc_site, alloc_site_map); | 1691 AddStoreMapConstant(alloc_site, alloc_site_map); |
| 1723 HObjectAccess access = HObjectAccess::ForAllocationSitePayload(); | 1692 HObjectAccess access = HObjectAccess::ForAllocationSitePayload(); |
| 1724 AddStore(alloc_site, access, payload); | 1693 AddStore(alloc_site, access, payload); |
| 1725 return alloc_site; | 1694 return alloc_site; |
| 1726 } | 1695 } |
| 1727 | 1696 |
| 1728 | 1697 |
| 1729 HInstruction* HGraphBuilder::BuildGetNativeContext(HValue* context) { | 1698 HInstruction* HGraphBuilder::BuildGetNativeContext(HValue* context) { |
| 1730 // Get the global context, then the native context | 1699 // Get the global context, then the native context |
| 1731 HInstruction* global_object = AddInstruction(new(zone()) | 1700 HInstruction* global_object = Add<HGlobalObject>(context); |
| 1732 HGlobalObject(context)); | |
| 1733 HObjectAccess access = HObjectAccess::ForJSObjectOffset( | 1701 HObjectAccess access = HObjectAccess::ForJSObjectOffset( |
| 1734 GlobalObject::kNativeContextOffset); | 1702 GlobalObject::kNativeContextOffset); |
| 1735 return AddLoad(global_object, access); | 1703 return AddLoad(global_object, access); |
| 1736 } | 1704 } |
| 1737 | 1705 |
| 1738 | 1706 |
| 1739 HInstruction* HGraphBuilder::BuildGetArrayFunction(HValue* context) { | 1707 HInstruction* HGraphBuilder::BuildGetArrayFunction(HValue* context) { |
| 1740 HInstruction* native_context = BuildGetNativeContext(context); | 1708 HInstruction* native_context = BuildGetNativeContext(context); |
| 1741 HInstruction* index = AddInstruction(new(zone()) | 1709 HInstruction* index = Add<HConstant>(Context::ARRAY_FUNCTION_INDEX); |
| 1742 HConstant(Context::ARRAY_FUNCTION_INDEX)); | 1710 return Add<HLoadKeyed>( |
| 1743 | 1711 native_context, index, static_cast<HValue*>(NULL), FAST_ELEMENTS); |
| 1744 return AddInstruction(new (zone()) | |
| 1745 HLoadKeyed(native_context, index, NULL, FAST_ELEMENTS)); | |
| 1746 } | 1712 } |
| 1747 | 1713 |
| 1748 | 1714 |
| 1749 HGraphBuilder::JSArrayBuilder::JSArrayBuilder(HGraphBuilder* builder, | 1715 HGraphBuilder::JSArrayBuilder::JSArrayBuilder(HGraphBuilder* builder, |
| 1750 ElementsKind kind, | 1716 ElementsKind kind, |
| 1751 HValue* allocation_site_payload, | 1717 HValue* allocation_site_payload, |
| 1752 bool disable_allocation_sites) : | 1718 bool disable_allocation_sites) : |
| 1753 builder_(builder), | 1719 builder_(builder), |
| 1754 kind_(kind), | 1720 kind_(kind), |
| 1755 allocation_site_payload_(allocation_site_payload), | 1721 allocation_site_payload_(allocation_site_payload), |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1767 kind_(kind), | 1733 kind_(kind), |
| 1768 mode_(DONT_TRACK_ALLOCATION_SITE), | 1734 mode_(DONT_TRACK_ALLOCATION_SITE), |
| 1769 allocation_site_payload_(NULL), | 1735 allocation_site_payload_(NULL), |
| 1770 constructor_function_(constructor_function) { | 1736 constructor_function_(constructor_function) { |
| 1771 } | 1737 } |
| 1772 | 1738 |
| 1773 | 1739 |
| 1774 HValue* HGraphBuilder::JSArrayBuilder::EmitMapCode(HValue* context) { | 1740 HValue* HGraphBuilder::JSArrayBuilder::EmitMapCode(HValue* context) { |
| 1775 HInstruction* native_context = builder()->BuildGetNativeContext(context); | 1741 HInstruction* native_context = builder()->BuildGetNativeContext(context); |
| 1776 | 1742 |
| 1777 HInstruction* index = builder()->AddInstruction(new(zone()) | 1743 HInstruction* index = builder()->Add<HConstant>(Context::JS_ARRAY_MAPS_INDEX); |
| 1778 HConstant(Context::JS_ARRAY_MAPS_INDEX)); | |
| 1779 | 1744 |
| 1780 HInstruction* map_array = builder()->AddInstruction(new(zone()) | 1745 HInstruction* map_array = builder()->Add<HLoadKeyed>( |
| 1781 HLoadKeyed(native_context, index, NULL, FAST_ELEMENTS)); | 1746 native_context, index, static_cast<HValue*>(NULL), FAST_ELEMENTS); |
| 1782 | 1747 |
| 1783 HInstruction* kind_index = builder()->AddInstruction(new(zone()) | 1748 HInstruction* kind_index = builder()->Add<HConstant>(kind_); |
| 1784 HConstant(kind_)); | |
| 1785 | 1749 |
| 1786 return builder()->AddInstruction(new(zone()) | 1750 return builder()->Add<HLoadKeyed>( |
| 1787 HLoadKeyed(map_array, kind_index, NULL, FAST_ELEMENTS)); | 1751 map_array, kind_index, static_cast<HValue*>(NULL), FAST_ELEMENTS); |
| 1788 } | 1752 } |
| 1789 | 1753 |
| 1790 | 1754 |
| 1791 HValue* HGraphBuilder::JSArrayBuilder::EmitInternalMapCode() { | 1755 HValue* HGraphBuilder::JSArrayBuilder::EmitInternalMapCode() { |
| 1792 // Find the map near the constructor function | 1756 // Find the map near the constructor function |
| 1793 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap(); | 1757 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap(); |
| 1794 return AddInstruction( | 1758 return builder()->AddInstruction( |
| 1795 builder()->BuildLoadNamedField(constructor_function_, | 1759 builder()->BuildLoadNamedField(constructor_function_, |
| 1796 access, | 1760 access, |
| 1797 Representation::Tagged())); | 1761 Representation::Tagged())); |
| 1798 } | 1762 } |
| 1799 | 1763 |
| 1800 | 1764 |
| 1801 HValue* HGraphBuilder::JSArrayBuilder::EstablishAllocationSize( | 1765 HValue* HGraphBuilder::JSArrayBuilder::EstablishAllocationSize( |
| 1802 HValue* length_node) { | 1766 HValue* length_node) { |
| 1803 HValue* context = builder()->environment()->LookupContext(); | 1767 HValue* context = builder()->environment()->LookupContext(); |
| 1804 ASSERT(length_node != NULL); | 1768 ASSERT(length_node != NULL); |
| 1805 | 1769 |
| 1806 int base_size = JSArray::kSize; | 1770 int base_size = JSArray::kSize; |
| 1807 if (mode_ == TRACK_ALLOCATION_SITE) { | 1771 if (mode_ == TRACK_ALLOCATION_SITE) { |
| 1808 base_size += AllocationSiteInfo::kSize; | 1772 base_size += AllocationSiteInfo::kSize; |
| 1809 } | 1773 } |
| 1810 | 1774 |
| 1811 if (IsFastDoubleElementsKind(kind_)) { | 1775 if (IsFastDoubleElementsKind(kind_)) { |
| 1812 base_size += FixedDoubleArray::kHeaderSize; | 1776 base_size += FixedDoubleArray::kHeaderSize; |
| 1813 } else { | 1777 } else { |
| 1814 base_size += FixedArray::kHeaderSize; | 1778 base_size += FixedArray::kHeaderSize; |
| 1815 } | 1779 } |
| 1816 | 1780 |
| 1817 HInstruction* elements_size_value = new(zone()) HConstant(elements_size()); | 1781 HInstruction* elements_size_value = |
| 1818 AddInstruction(elements_size_value); | 1782 builder()->Add<HConstant>(elements_size()); |
| 1819 HInstruction* mul = HMul::New(zone(), context, length_node, | 1783 HInstruction* mul = HMul::New(zone(), context, length_node, |
| 1820 elements_size_value); | 1784 elements_size_value); |
| 1821 mul->ClearFlag(HValue::kCanOverflow); | 1785 mul->ClearFlag(HValue::kCanOverflow); |
| 1822 AddInstruction(mul); | 1786 builder()->AddInstruction(mul); |
| 1823 | 1787 |
| 1824 HInstruction* base = new(zone()) HConstant(base_size); | 1788 HInstruction* base = builder()->Add<HConstant>(base_size); |
| 1825 AddInstruction(base); | |
| 1826 HInstruction* total_size = HAdd::New(zone(), context, base, mul); | 1789 HInstruction* total_size = HAdd::New(zone(), context, base, mul); |
| 1827 total_size->ClearFlag(HValue::kCanOverflow); | 1790 total_size->ClearFlag(HValue::kCanOverflow); |
| 1828 AddInstruction(total_size); | 1791 builder()->AddInstruction(total_size); |
| 1829 return total_size; | 1792 return total_size; |
| 1830 } | 1793 } |
| 1831 | 1794 |
| 1832 | 1795 |
| 1833 HValue* HGraphBuilder::JSArrayBuilder::EstablishEmptyArrayAllocationSize() { | 1796 HValue* HGraphBuilder::JSArrayBuilder::EstablishEmptyArrayAllocationSize() { |
| 1834 int base_size = JSArray::kSize; | 1797 int base_size = JSArray::kSize; |
| 1835 if (mode_ == TRACK_ALLOCATION_SITE) { | 1798 if (mode_ == TRACK_ALLOCATION_SITE) { |
| 1836 base_size += AllocationSiteInfo::kSize; | 1799 base_size += AllocationSiteInfo::kSize; |
| 1837 } | 1800 } |
| 1838 | 1801 |
| 1839 base_size += IsFastDoubleElementsKind(kind_) | 1802 base_size += IsFastDoubleElementsKind(kind_) |
| 1840 ? FixedDoubleArray::SizeFor(initial_capacity()) | 1803 ? FixedDoubleArray::SizeFor(initial_capacity()) |
| 1841 : FixedArray::SizeFor(initial_capacity()); | 1804 : FixedArray::SizeFor(initial_capacity()); |
| 1842 | 1805 |
| 1843 HConstant* array_size = new(zone()) HConstant(base_size); | 1806 return builder()->Add<HConstant>(base_size); |
| 1844 AddInstruction(array_size); | |
| 1845 return array_size; | |
| 1846 } | 1807 } |
| 1847 | 1808 |
| 1848 | 1809 |
| 1849 HValue* HGraphBuilder::JSArrayBuilder::AllocateEmptyArray() { | 1810 HValue* HGraphBuilder::JSArrayBuilder::AllocateEmptyArray() { |
| 1850 HValue* size_in_bytes = EstablishEmptyArrayAllocationSize(); | 1811 HValue* size_in_bytes = EstablishEmptyArrayAllocationSize(); |
| 1851 HConstant* capacity = new(zone()) HConstant(initial_capacity()); | 1812 HConstant* capacity = builder()->Add<HConstant>(initial_capacity()); |
| 1852 AddInstruction(capacity); | |
| 1853 return AllocateArray(size_in_bytes, | 1813 return AllocateArray(size_in_bytes, |
| 1854 capacity, | 1814 capacity, |
| 1855 builder()->graph()->GetConstant0(), | 1815 builder()->graph()->GetConstant0(), |
| 1856 true); | 1816 true); |
| 1857 } | 1817 } |
| 1858 | 1818 |
| 1859 | 1819 |
| 1860 HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(HValue* capacity, | 1820 HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(HValue* capacity, |
| 1861 HValue* length_field, | 1821 HValue* length_field, |
| 1862 bool fill_with_hole) { | 1822 bool fill_with_hole) { |
| 1863 HValue* size_in_bytes = EstablishAllocationSize(capacity); | 1823 HValue* size_in_bytes = EstablishAllocationSize(capacity); |
| 1864 return AllocateArray(size_in_bytes, capacity, length_field, fill_with_hole); | 1824 return AllocateArray(size_in_bytes, capacity, length_field, fill_with_hole); |
| 1865 } | 1825 } |
| 1866 | 1826 |
| 1867 | 1827 |
| 1868 HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(HValue* size_in_bytes, | 1828 HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(HValue* size_in_bytes, |
| 1869 HValue* capacity, | 1829 HValue* capacity, |
| 1870 HValue* length_field, | 1830 HValue* length_field, |
| 1871 bool fill_with_hole) { | 1831 bool fill_with_hole) { |
| 1872 HValue* context = builder()->environment()->LookupContext(); | 1832 HValue* context = builder()->environment()->LookupContext(); |
| 1873 | 1833 |
| 1874 // Allocate (dealing with failure appropriately) | 1834 // Allocate (dealing with failure appropriately) |
| 1875 HAllocate::Flags flags = HAllocate::DefaultFlags(kind_); | 1835 HAllocate::Flags flags = HAllocate::DefaultFlags(kind_); |
| 1876 HAllocate* new_object = new(zone()) HAllocate(context, size_in_bytes, | 1836 HAllocate* new_object = builder()->Add<HAllocate>(context, size_in_bytes, |
| 1877 HType::JSArray(), flags); | 1837 HType::JSArray(), flags); |
| 1878 AddInstruction(new_object); | |
| 1879 | 1838 |
| 1880 // Fill in the fields: map, properties, length | 1839 // Fill in the fields: map, properties, length |
| 1881 HValue* map; | 1840 HValue* map; |
| 1882 if (constructor_function_ != NULL) { | 1841 if (constructor_function_ != NULL) { |
| 1883 map = EmitInternalMapCode(); | 1842 map = EmitInternalMapCode(); |
| 1884 } else { | 1843 } else { |
| 1885 map = EmitMapCode(context); | 1844 map = EmitMapCode(context); |
| 1886 } | 1845 } |
| 1887 elements_location_ = builder()->BuildJSArrayHeader(new_object, | 1846 elements_location_ = builder()->BuildJSArrayHeader(new_object, |
| 1888 map, | 1847 map, |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1899 } | 1858 } |
| 1900 | 1859 |
| 1901 return new_object; | 1860 return new_object; |
| 1902 } | 1861 } |
| 1903 | 1862 |
| 1904 | 1863 |
| 1905 HStoreNamedField* HGraphBuilder::AddStore(HValue *object, | 1864 HStoreNamedField* HGraphBuilder::AddStore(HValue *object, |
| 1906 HObjectAccess access, | 1865 HObjectAccess access, |
| 1907 HValue *val, | 1866 HValue *val, |
| 1908 Representation representation) { | 1867 Representation representation) { |
| 1909 HStoreNamedField *instr = new(zone()) | 1868 return Add<HStoreNamedField>(object, access, val, representation); |
| 1910 HStoreNamedField(object, access, val, representation); | |
| 1911 AddInstruction(instr); | |
| 1912 return instr; | |
| 1913 } | 1869 } |
| 1914 | 1870 |
| 1915 | 1871 |
| 1916 HLoadNamedField* HGraphBuilder::AddLoad(HValue *object, | 1872 HLoadNamedField* HGraphBuilder::AddLoad(HValue *object, |
| 1917 HObjectAccess access, | 1873 HObjectAccess access, |
| 1918 HValue *typecheck, | 1874 HValue *typecheck, |
| 1919 Representation representation) { | 1875 Representation representation) { |
| 1920 HLoadNamedField *instr = | 1876 return Add<HLoadNamedField>(object, access, typecheck, representation); |
| 1921 new(zone()) HLoadNamedField(object, access, typecheck, representation); | |
| 1922 AddInstruction(instr); | |
| 1923 return instr; | |
| 1924 } | 1877 } |
| 1925 | 1878 |
| 1926 | 1879 |
| 1927 HStoreNamedField* HGraphBuilder::AddStoreMapConstant(HValue *object, | 1880 HStoreNamedField* HGraphBuilder::AddStoreMapConstant(HValue *object, |
| 1928 Handle<Map> map) { | 1881 Handle<Map> map) { |
| 1929 HValue* constant = AddInstruction(new(zone()) HConstant(map)); | 1882 return Add<HStoreNamedField>(object, HObjectAccess::ForMap(), |
| 1930 HStoreNamedField *instr = | 1883 Add<HConstant>(map)); |
| 1931 new(zone()) HStoreNamedField(object, HObjectAccess::ForMap(), constant); | |
| 1932 AddInstruction(instr); | |
| 1933 return instr; | |
| 1934 } | 1884 } |
| 1935 | 1885 |
| 1936 | 1886 |
| 1937 HOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info) | 1887 HOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info) |
| 1938 : HGraphBuilder(info), | 1888 : HGraphBuilder(info), |
| 1939 function_state_(NULL), | 1889 function_state_(NULL), |
| 1940 initial_function_state_(this, info, NORMAL_RETURN), | 1890 initial_function_state_(this, info, NORMAL_RETURN), |
| 1941 ast_context_(NULL), | 1891 ast_context_(NULL), |
| 1942 break_scope_(NULL), | 1892 break_scope_(NULL), |
| 1943 inlined_count_(0), | 1893 inlined_count_(0), |
| (...skipping 1751 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3695 void HOptimizedGraphBuilder::VisitForControl(Expression* expr, | 3645 void HOptimizedGraphBuilder::VisitForControl(Expression* expr, |
| 3696 HBasicBlock* true_block, | 3646 HBasicBlock* true_block, |
| 3697 HBasicBlock* false_block) { | 3647 HBasicBlock* false_block) { |
| 3698 TestContext for_test(this, expr, true_block, false_block); | 3648 TestContext for_test(this, expr, true_block, false_block); |
| 3699 Visit(expr); | 3649 Visit(expr); |
| 3700 } | 3650 } |
| 3701 | 3651 |
| 3702 | 3652 |
| 3703 void HOptimizedGraphBuilder::VisitArgument(Expression* expr) { | 3653 void HOptimizedGraphBuilder::VisitArgument(Expression* expr) { |
| 3704 CHECK_ALIVE(VisitForValue(expr)); | 3654 CHECK_ALIVE(VisitForValue(expr)); |
| 3705 Push(AddInstruction(new(zone()) HPushArgument(Pop()))); | 3655 Push(Add<HPushArgument>(Pop())); |
| 3706 } | 3656 } |
| 3707 | 3657 |
| 3708 | 3658 |
| 3709 void HOptimizedGraphBuilder::VisitArgumentList( | 3659 void HOptimizedGraphBuilder::VisitArgumentList( |
| 3710 ZoneList<Expression*>* arguments) { | 3660 ZoneList<Expression*>* arguments) { |
| 3711 for (int i = 0; i < arguments->length(); i++) { | 3661 for (int i = 0; i < arguments->length(); i++) { |
| 3712 CHECK_ALIVE(VisitArgument(arguments->at(i))); | 3662 CHECK_ALIVE(VisitArgument(arguments->at(i))); |
| 3713 } | 3663 } |
| 3714 } | 3664 } |
| 3715 | 3665 |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3761 | 3711 |
| 3762 // Handle implicit declaration of the function name in named function | 3712 // Handle implicit declaration of the function name in named function |
| 3763 // expressions before other declarations. | 3713 // expressions before other declarations. |
| 3764 if (scope->is_function_scope() && scope->function() != NULL) { | 3714 if (scope->is_function_scope() && scope->function() != NULL) { |
| 3765 VisitVariableDeclaration(scope->function()); | 3715 VisitVariableDeclaration(scope->function()); |
| 3766 } | 3716 } |
| 3767 VisitDeclarations(scope->declarations()); | 3717 VisitDeclarations(scope->declarations()); |
| 3768 AddSimulate(BailoutId::Declarations()); | 3718 AddSimulate(BailoutId::Declarations()); |
| 3769 | 3719 |
| 3770 HValue* context = environment()->LookupContext(); | 3720 HValue* context = environment()->LookupContext(); |
| 3771 AddInstruction( | 3721 Add<HStackCheck>(context, HStackCheck::kFunctionEntry); |
| 3772 new(zone()) HStackCheck(context, HStackCheck::kFunctionEntry)); | |
| 3773 | 3722 |
| 3774 VisitStatements(current_info()->function()->body()); | 3723 VisitStatements(current_info()->function()->body()); |
| 3775 if (HasStackOverflow()) return false; | 3724 if (HasStackOverflow()) return false; |
| 3776 | 3725 |
| 3777 if (current_block() != NULL) { | 3726 if (current_block() != NULL) { |
| 3778 AddReturn(graph()->GetConstantUndefined()); | 3727 AddReturn(graph()->GetConstantUndefined()); |
| 3779 set_current_block(NULL); | 3728 set_current_block(NULL); |
| 3780 } | 3729 } |
| 3781 | 3730 |
| 3782 // If the checksum of the number of type info changes is the same as the | 3731 // If the checksum of the number of type info changes is the same as the |
| (...skipping 705 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4488 void HOptimizedGraphBuilder::PushAndAdd(HInstruction* instr) { | 4437 void HOptimizedGraphBuilder::PushAndAdd(HInstruction* instr) { |
| 4489 Push(instr); | 4438 Push(instr); |
| 4490 AddInstruction(instr); | 4439 AddInstruction(instr); |
| 4491 } | 4440 } |
| 4492 | 4441 |
| 4493 | 4442 |
| 4494 void HOptimizedGraphBuilder::AddSoftDeoptimize() { | 4443 void HOptimizedGraphBuilder::AddSoftDeoptimize() { |
| 4495 isolate()->counters()->soft_deopts_requested()->Increment(); | 4444 isolate()->counters()->soft_deopts_requested()->Increment(); |
| 4496 if (FLAG_always_opt) return; | 4445 if (FLAG_always_opt) return; |
| 4497 if (current_block()->IsDeoptimizing()) return; | 4446 if (current_block()->IsDeoptimizing()) return; |
| 4498 AddInstruction(new(zone()) HSoftDeoptimize()); | 4447 Add<HSoftDeoptimize>(); |
| 4499 isolate()->counters()->soft_deopts_inserted()->Increment(); | 4448 isolate()->counters()->soft_deopts_inserted()->Increment(); |
| 4500 current_block()->MarkAsDeoptimizing(); | 4449 current_block()->MarkAsDeoptimizing(); |
| 4501 graph()->set_has_soft_deoptimize(true); | 4450 graph()->set_has_soft_deoptimize(true); |
| 4502 } | 4451 } |
| 4503 | 4452 |
| 4504 | 4453 |
| 4505 template <class Instruction> | 4454 template <class Instruction> |
| 4506 HInstruction* HOptimizedGraphBuilder::PreProcessCall(Instruction* call) { | 4455 HInstruction* HOptimizedGraphBuilder::PreProcessCall(Instruction* call) { |
| 4507 int count = call->argument_count(); | 4456 int count = call->argument_count(); |
| 4508 ZoneList<HValue*> arguments(count, zone()); | 4457 ZoneList<HValue*> arguments(count, zone()); |
| 4509 for (int i = 0; i < count; ++i) { | 4458 for (int i = 0; i < count; ++i) { |
| 4510 arguments.Add(Pop(), zone()); | 4459 arguments.Add(Pop(), zone()); |
| 4511 } | 4460 } |
| 4512 | 4461 |
| 4513 while (!arguments.is_empty()) { | 4462 while (!arguments.is_empty()) { |
| 4514 AddInstruction(new(zone()) HPushArgument(arguments.RemoveLast())); | 4463 Add<HPushArgument>(arguments.RemoveLast()); |
| 4515 } | 4464 } |
| 4516 return call; | 4465 return call; |
| 4517 } | 4466 } |
| 4518 | 4467 |
| 4519 | 4468 |
| 4520 void HOptimizedGraphBuilder::SetUpScope(Scope* scope) { | 4469 void HOptimizedGraphBuilder::SetUpScope(Scope* scope) { |
| 4521 HConstant* undefined_constant = new(zone()) HConstant( | 4470 HConstant* undefined_constant = Add<HConstant>( |
| 4522 isolate()->factory()->undefined_value()); | 4471 isolate()->factory()->undefined_value()); |
| 4523 AddInstruction(undefined_constant); | |
| 4524 graph()->set_undefined_constant(undefined_constant); | 4472 graph()->set_undefined_constant(undefined_constant); |
| 4525 | 4473 |
| 4526 // Create an arguments object containing the initial parameters. Set the | 4474 // Create an arguments object containing the initial parameters. Set the |
| 4527 // initial values of parameters including "this" having parameter index 0. | 4475 // initial values of parameters including "this" having parameter index 0. |
| 4528 ASSERT_EQ(scope->num_parameters() + 1, environment()->parameter_count()); | 4476 ASSERT_EQ(scope->num_parameters() + 1, environment()->parameter_count()); |
| 4529 HArgumentsObject* arguments_object = | 4477 HArgumentsObject* arguments_object = |
| 4530 new(zone()) HArgumentsObject(environment()->parameter_count(), zone()); | 4478 new(zone()) HArgumentsObject(environment()->parameter_count(), zone()); |
| 4531 for (int i = 0; i < environment()->parameter_count(); ++i) { | 4479 for (int i = 0; i < environment()->parameter_count(); ++i) { |
| 4532 HInstruction* parameter = AddInstruction(new(zone()) HParameter(i)); | 4480 HInstruction* parameter = Add<HParameter>(i); |
| 4533 arguments_object->AddArgument(parameter, zone()); | 4481 arguments_object->AddArgument(parameter, zone()); |
| 4534 environment()->Bind(i, parameter); | 4482 environment()->Bind(i, parameter); |
| 4535 } | 4483 } |
| 4536 AddInstruction(arguments_object); | 4484 AddInstruction(arguments_object); |
| 4537 graph()->SetArgumentsObject(arguments_object); | 4485 graph()->SetArgumentsObject(arguments_object); |
| 4538 | 4486 |
| 4539 // First special is HContext. | 4487 // First special is HContext. |
| 4540 HInstruction* context = AddInstruction(new(zone()) HContext); | 4488 HInstruction* context = Add<HContext>(); |
| 4541 environment()->BindContext(context); | 4489 environment()->BindContext(context); |
| 4542 | 4490 |
| 4543 // Initialize specials and locals to undefined. | 4491 // Initialize specials and locals to undefined. |
| 4544 for (int i = environment()->parameter_count() + 1; | 4492 for (int i = environment()->parameter_count() + 1; |
| 4545 i < environment()->length(); | 4493 i < environment()->length(); |
| 4546 ++i) { | 4494 ++i) { |
| 4547 environment()->Bind(i, undefined_constant); | 4495 environment()->Bind(i, undefined_constant); |
| 4548 } | 4496 } |
| 4549 | 4497 |
| 4550 // Handle the arguments and arguments shadow variables specially (they do | 4498 // Handle the arguments and arguments shadow variables specially (they do |
| (...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4969 | 4917 |
| 4970 set_current_block(osr_entry); | 4918 set_current_block(osr_entry); |
| 4971 osr_entry->set_osr_entry(); | 4919 osr_entry->set_osr_entry(); |
| 4972 BailoutId osr_entry_id = statement->OsrEntryId(); | 4920 BailoutId osr_entry_id = statement->OsrEntryId(); |
| 4973 int first_expression_index = environment()->first_expression_index(); | 4921 int first_expression_index = environment()->first_expression_index(); |
| 4974 int length = environment()->length(); | 4922 int length = environment()->length(); |
| 4975 ZoneList<HUnknownOSRValue*>* osr_values = | 4923 ZoneList<HUnknownOSRValue*>* osr_values = |
| 4976 new(zone()) ZoneList<HUnknownOSRValue*>(length, zone()); | 4924 new(zone()) ZoneList<HUnknownOSRValue*>(length, zone()); |
| 4977 | 4925 |
| 4978 for (int i = 0; i < first_expression_index; ++i) { | 4926 for (int i = 0; i < first_expression_index; ++i) { |
| 4979 HUnknownOSRValue* osr_value = new(zone()) HUnknownOSRValue; | 4927 HUnknownOSRValue* osr_value = Add<HUnknownOSRValue>(); |
| 4980 AddInstruction(osr_value); | |
| 4981 environment()->Bind(i, osr_value); | 4928 environment()->Bind(i, osr_value); |
| 4982 osr_values->Add(osr_value, zone()); | 4929 osr_values->Add(osr_value, zone()); |
| 4983 } | 4930 } |
| 4984 | 4931 |
| 4985 if (first_expression_index != length) { | 4932 if (first_expression_index != length) { |
| 4986 environment()->Drop(length - first_expression_index); | 4933 environment()->Drop(length - first_expression_index); |
| 4987 for (int i = first_expression_index; i < length; ++i) { | 4934 for (int i = first_expression_index; i < length; ++i) { |
| 4988 HUnknownOSRValue* osr_value = new(zone()) HUnknownOSRValue; | 4935 HUnknownOSRValue* osr_value = Add<HUnknownOSRValue>(); |
| 4989 AddInstruction(osr_value); | |
| 4990 environment()->Push(osr_value); | 4936 environment()->Push(osr_value); |
| 4991 osr_values->Add(osr_value, zone()); | 4937 osr_values->Add(osr_value, zone()); |
| 4992 } | 4938 } |
| 4993 } | 4939 } |
| 4994 | 4940 |
| 4995 graph()->set_osr_values(osr_values); | 4941 graph()->set_osr_values(osr_values); |
| 4996 | 4942 |
| 4997 AddSimulate(osr_entry_id); | 4943 AddSimulate(osr_entry_id); |
| 4998 AddInstruction(new(zone()) HOsrEntry(osr_entry_id)); | 4944 Add<HOsrEntry>(osr_entry_id); |
| 4999 HContext* context = new(zone()) HContext; | 4945 HContext* context = Add<HContext>(); |
| 5000 AddInstruction(context); | |
| 5001 environment()->BindContext(context); | 4946 environment()->BindContext(context); |
| 5002 current_block()->Goto(loop_predecessor); | 4947 current_block()->Goto(loop_predecessor); |
| 5003 loop_predecessor->SetJoinId(statement->EntryId()); | 4948 loop_predecessor->SetJoinId(statement->EntryId()); |
| 5004 set_current_block(loop_predecessor); | 4949 set_current_block(loop_predecessor); |
| 5005 return true; | 4950 return true; |
| 5006 } | 4951 } |
| 5007 | 4952 |
| 5008 | 4953 |
| 5009 void HOptimizedGraphBuilder::VisitLoopBody(IterationStatement* stmt, | 4954 void HOptimizedGraphBuilder::VisitLoopBody(IterationStatement* stmt, |
| 5010 HBasicBlock* loop_entry, | 4955 HBasicBlock* loop_entry, |
| 5011 BreakAndContinueInfo* break_info) { | 4956 BreakAndContinueInfo* break_info) { |
| 5012 BreakAndContinueScope push(break_info, this); | 4957 BreakAndContinueScope push(break_info, this); |
| 5013 AddSimulate(stmt->StackCheckId()); | 4958 AddSimulate(stmt->StackCheckId()); |
| 5014 HValue* context = environment()->LookupContext(); | 4959 HValue* context = environment()->LookupContext(); |
| 5015 HStackCheck* stack_check = | 4960 HStackCheck* stack_check = Add<HStackCheck>( |
| 5016 new(zone()) HStackCheck(context, HStackCheck::kBackwardsBranch); | 4961 context, HStackCheck::kBackwardsBranch); |
| 5017 AddInstruction(stack_check); | |
| 5018 ASSERT(loop_entry->IsLoopHeader()); | 4962 ASSERT(loop_entry->IsLoopHeader()); |
| 5019 loop_entry->loop_information()->set_stack_check(stack_check); | 4963 loop_entry->loop_information()->set_stack_check(stack_check); |
| 5020 CHECK_BAILOUT(Visit(stmt->body())); | 4964 CHECK_BAILOUT(Visit(stmt->body())); |
| 5021 } | 4965 } |
| 5022 | 4966 |
| 5023 | 4967 |
| 5024 void HOptimizedGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) { | 4968 void HOptimizedGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) { |
| 5025 ASSERT(!HasStackOverflow()); | 4969 ASSERT(!HasStackOverflow()); |
| 5026 ASSERT(current_block() != NULL); | 4970 ASSERT(current_block() != NULL); |
| 5027 ASSERT(current_block()->HasPredecessor()); | 4971 ASSERT(current_block()->HasPredecessor()); |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5176 if (!stmt->each()->IsVariableProxy() || | 5120 if (!stmt->each()->IsVariableProxy() || |
| 5177 !stmt->each()->AsVariableProxy()->var()->IsStackLocal()) { | 5121 !stmt->each()->AsVariableProxy()->var()->IsStackLocal()) { |
| 5178 return Bailout("ForInStatement with non-local each variable"); | 5122 return Bailout("ForInStatement with non-local each variable"); |
| 5179 } | 5123 } |
| 5180 | 5124 |
| 5181 Variable* each_var = stmt->each()->AsVariableProxy()->var(); | 5125 Variable* each_var = stmt->each()->AsVariableProxy()->var(); |
| 5182 | 5126 |
| 5183 CHECK_ALIVE(VisitForValue(stmt->enumerable())); | 5127 CHECK_ALIVE(VisitForValue(stmt->enumerable())); |
| 5184 HValue* enumerable = Top(); // Leave enumerable at the top. | 5128 HValue* enumerable = Top(); // Leave enumerable at the top. |
| 5185 | 5129 |
| 5186 HInstruction* map = AddInstruction(new(zone()) HForInPrepareMap( | 5130 HInstruction* map = Add<HForInPrepareMap>( |
| 5187 environment()->LookupContext(), enumerable)); | 5131 environment()->LookupContext(), enumerable); |
| 5188 AddSimulate(stmt->PrepareId()); | 5132 AddSimulate(stmt->PrepareId()); |
| 5189 | 5133 |
| 5190 HInstruction* array = AddInstruction( | 5134 HInstruction* array = Add<HForInCacheArray>( |
| 5191 new(zone()) HForInCacheArray( | 5135 enumerable, map, DescriptorArray::kEnumCacheBridgeCacheIndex); |
| 5192 enumerable, | |
| 5193 map, | |
| 5194 DescriptorArray::kEnumCacheBridgeCacheIndex)); | |
| 5195 | 5136 |
| 5196 HInstruction* enum_length = AddInstruction(new(zone()) HMapEnumLength(map)); | 5137 HInstruction* enum_length = Add<HMapEnumLength>(map); |
| 5197 | 5138 |
| 5198 HInstruction* start_index = AddInstruction(new(zone()) HConstant(0)); | 5139 HInstruction* start_index = Add<HConstant>(0); |
| 5199 | 5140 |
| 5200 Push(map); | 5141 Push(map); |
| 5201 Push(array); | 5142 Push(array); |
| 5202 Push(enum_length); | 5143 Push(enum_length); |
| 5203 Push(start_index); | 5144 Push(start_index); |
| 5204 | 5145 |
| 5205 HInstruction* index_cache = AddInstruction( | 5146 HInstruction* index_cache = Add<HForInCacheArray>( |
| 5206 new(zone()) HForInCacheArray( | 5147 enumerable, map, DescriptorArray::kEnumCacheBridgeIndicesCacheIndex); |
| 5207 enumerable, | |
| 5208 map, | |
| 5209 DescriptorArray::kEnumCacheBridgeIndicesCacheIndex)); | |
| 5210 HForInCacheArray::cast(array)->set_index_cache( | 5148 HForInCacheArray::cast(array)->set_index_cache( |
| 5211 HForInCacheArray::cast(index_cache)); | 5149 HForInCacheArray::cast(index_cache)); |
| 5212 | 5150 |
| 5213 bool osr_entry = PreProcessOsrEntry(stmt); | 5151 bool osr_entry = PreProcessOsrEntry(stmt); |
| 5214 HBasicBlock* loop_entry = CreateLoopHeaderBlock(); | 5152 HBasicBlock* loop_entry = CreateLoopHeaderBlock(); |
| 5215 current_block()->Goto(loop_entry); | 5153 current_block()->Goto(loop_entry); |
| 5216 set_current_block(loop_entry); | 5154 set_current_block(loop_entry); |
| 5217 if (osr_entry) graph()->set_osr_loop_entry(loop_entry); | 5155 if (osr_entry) graph()->set_osr_loop_entry(loop_entry); |
| 5218 | 5156 |
| 5219 HValue* index = environment()->ExpressionStackAt(0); | 5157 HValue* index = environment()->ExpressionStackAt(0); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 5230 | 5168 |
| 5231 compare_index->SetSuccessorAt(0, loop_body); | 5169 compare_index->SetSuccessorAt(0, loop_body); |
| 5232 compare_index->SetSuccessorAt(1, loop_successor); | 5170 compare_index->SetSuccessorAt(1, loop_successor); |
| 5233 current_block()->Finish(compare_index); | 5171 current_block()->Finish(compare_index); |
| 5234 | 5172 |
| 5235 set_current_block(loop_successor); | 5173 set_current_block(loop_successor); |
| 5236 Drop(5); | 5174 Drop(5); |
| 5237 | 5175 |
| 5238 set_current_block(loop_body); | 5176 set_current_block(loop_body); |
| 5239 | 5177 |
| 5240 HValue* key = AddInstruction( | 5178 HValue* key = Add<HLoadKeyed>( |
| 5241 new(zone()) HLoadKeyed( | 5179 environment()->ExpressionStackAt(2), // Enum cache. |
| 5242 environment()->ExpressionStackAt(2), // Enum cache. | 5180 environment()->ExpressionStackAt(0), // Iteration index. |
| 5243 environment()->ExpressionStackAt(0), // Iteration index. | 5181 environment()->ExpressionStackAt(0), |
| 5244 environment()->ExpressionStackAt(0), | 5182 FAST_ELEMENTS); |
| 5245 FAST_ELEMENTS)); | |
| 5246 | 5183 |
| 5247 // Check if the expected map still matches that of the enumerable. | 5184 // Check if the expected map still matches that of the enumerable. |
| 5248 // If not just deoptimize. | 5185 // If not just deoptimize. |
| 5249 AddInstruction(new(zone()) HCheckMapValue( | 5186 Add<HCheckMapValue>(environment()->ExpressionStackAt(4), |
| 5250 environment()->ExpressionStackAt(4), | 5187 environment()->ExpressionStackAt(3)); |
| 5251 environment()->ExpressionStackAt(3))); | |
| 5252 | 5188 |
| 5253 Bind(each_var, key); | 5189 Bind(each_var, key); |
| 5254 | 5190 |
| 5255 BreakAndContinueInfo break_info(stmt, 5); | 5191 BreakAndContinueInfo break_info(stmt, 5); |
| 5256 CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry, &break_info)); | 5192 CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry, &break_info)); |
| 5257 | 5193 |
| 5258 HBasicBlock* body_exit = | 5194 HBasicBlock* body_exit = |
| 5259 JoinContinue(stmt, current_block(), break_info.continue_block()); | 5195 JoinContinue(stmt, current_block(), break_info.continue_block()); |
| 5260 | 5196 |
| 5261 if (body_exit != NULL) { | 5197 if (body_exit != NULL) { |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5414 | 5350 |
| 5415 return kUseCell; | 5351 return kUseCell; |
| 5416 } | 5352 } |
| 5417 | 5353 |
| 5418 | 5354 |
| 5419 HValue* HOptimizedGraphBuilder::BuildContextChainWalk(Variable* var) { | 5355 HValue* HOptimizedGraphBuilder::BuildContextChainWalk(Variable* var) { |
| 5420 ASSERT(var->IsContextSlot()); | 5356 ASSERT(var->IsContextSlot()); |
| 5421 HValue* context = environment()->LookupContext(); | 5357 HValue* context = environment()->LookupContext(); |
| 5422 int length = current_info()->scope()->ContextChainLength(var->scope()); | 5358 int length = current_info()->scope()->ContextChainLength(var->scope()); |
| 5423 while (length-- > 0) { | 5359 while (length-- > 0) { |
| 5424 HInstruction* context_instruction = new(zone()) HOuterContext(context); | 5360 context = Add<HOuterContext>(context); |
| 5425 AddInstruction(context_instruction); | |
| 5426 context = context_instruction; | |
| 5427 } | 5361 } |
| 5428 return context; | 5362 return context; |
| 5429 } | 5363 } |
| 5430 | 5364 |
| 5431 | 5365 |
| 5432 void HOptimizedGraphBuilder::VisitVariableProxy(VariableProxy* expr) { | 5366 void HOptimizedGraphBuilder::VisitVariableProxy(VariableProxy* expr) { |
| 5433 ASSERT(!HasStackOverflow()); | 5367 ASSERT(!HasStackOverflow()); |
| 5434 ASSERT(current_block() != NULL); | 5368 ASSERT(current_block() != NULL); |
| 5435 ASSERT(current_block()->HasPredecessor()); | 5369 ASSERT(current_block()->HasPredecessor()); |
| 5436 Variable* variable = expr->var(); | 5370 Variable* variable = expr->var(); |
| (...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5722 } else { | 5656 } else { |
| 5723 NoObservableSideEffectsScope no_effects(this); | 5657 NoObservableSideEffectsScope no_effects(this); |
| 5724 Handle<FixedArray> closure_literals(closure->literals(), isolate()); | 5658 Handle<FixedArray> closure_literals(closure->literals(), isolate()); |
| 5725 Handle<FixedArray> constant_properties = expr->constant_properties(); | 5659 Handle<FixedArray> constant_properties = expr->constant_properties(); |
| 5726 int literal_index = expr->literal_index(); | 5660 int literal_index = expr->literal_index(); |
| 5727 int flags = expr->fast_elements() | 5661 int flags = expr->fast_elements() |
| 5728 ? ObjectLiteral::kFastElements : ObjectLiteral::kNoFlags; | 5662 ? ObjectLiteral::kFastElements : ObjectLiteral::kNoFlags; |
| 5729 flags |= expr->has_function() | 5663 flags |= expr->has_function() |
| 5730 ? ObjectLiteral::kHasFunction : ObjectLiteral::kNoFlags; | 5664 ? ObjectLiteral::kHasFunction : ObjectLiteral::kNoFlags; |
| 5731 | 5665 |
| 5732 AddInstruction(new(zone()) HPushArgument(AddInstruction( | 5666 Add<HPushArgument>(Add<HConstant>(closure_literals)); |
| 5733 new(zone()) HConstant(closure_literals)))); | 5667 Add<HPushArgument>(Add<HConstant>(literal_index)); |
| 5734 AddInstruction(new(zone()) HPushArgument(AddInstruction( | 5668 Add<HPushArgument>(Add<HConstant>(constant_properties)); |
| 5735 new(zone()) HConstant(literal_index)))); | 5669 Add<HPushArgument>(Add<HConstant>(flags)); |
| 5736 AddInstruction(new(zone()) HPushArgument(AddInstruction( | |
| 5737 new(zone()) HConstant(constant_properties)))); | |
| 5738 AddInstruction(new(zone()) HPushArgument(AddInstruction( | |
| 5739 new(zone()) HConstant(flags)))); | |
| 5740 | 5670 |
| 5741 Runtime::FunctionId function_id = | 5671 Runtime::FunctionId function_id = |
| 5742 (expr->depth() > 1 || expr->may_store_doubles()) | 5672 (expr->depth() > 1 || expr->may_store_doubles()) |
| 5743 ? Runtime::kCreateObjectLiteral : Runtime::kCreateObjectLiteralShallow; | 5673 ? Runtime::kCreateObjectLiteral : Runtime::kCreateObjectLiteralShallow; |
| 5744 literal = AddInstruction( | 5674 literal = Add<HCallRuntime>(context, |
| 5745 new(zone()) HCallRuntime(context, | 5675 isolate()->factory()->empty_string(), |
| 5746 isolate()->factory()->empty_string(), | 5676 Runtime::FunctionForId(function_id), |
| 5747 Runtime::FunctionForId(function_id), | 5677 4); |
| 5748 4)); | |
| 5749 } | 5678 } |
| 5750 | 5679 |
| 5751 // The object is expected in the bailout environment during computation | 5680 // The object is expected in the bailout environment during computation |
| 5752 // of the property values and is the value of the entire expression. | 5681 // of the property values and is the value of the entire expression. |
| 5753 Push(literal); | 5682 Push(literal); |
| 5754 | 5683 |
| 5755 expr->CalculateEmitStore(zone()); | 5684 expr->CalculateEmitStore(zone()); |
| 5756 | 5685 |
| 5757 for (int i = 0; i < expr->properties()->length(); i++) { | 5686 for (int i = 0; i < expr->properties()->length(); i++) { |
| 5758 ObjectLiteral::Property* property = expr->properties()->at(i); | 5687 ObjectLiteral::Property* property = expr->properties()->at(i); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5804 default: UNREACHABLE(); | 5733 default: UNREACHABLE(); |
| 5805 } | 5734 } |
| 5806 } | 5735 } |
| 5807 | 5736 |
| 5808 if (expr->has_function()) { | 5737 if (expr->has_function()) { |
| 5809 // Return the result of the transformation to fast properties | 5738 // Return the result of the transformation to fast properties |
| 5810 // instead of the original since this operation changes the map | 5739 // instead of the original since this operation changes the map |
| 5811 // of the object. This makes sure that the original object won't | 5740 // of the object. This makes sure that the original object won't |
| 5812 // be used by other optimized code before it is transformed | 5741 // be used by other optimized code before it is transformed |
| 5813 // (e.g. because of code motion). | 5742 // (e.g. because of code motion). |
| 5814 HToFastProperties* result = new(zone()) HToFastProperties(Pop()); | 5743 HToFastProperties* result = Add<HToFastProperties>(Pop()); |
| 5815 AddInstruction(result); | |
| 5816 return ast_context()->ReturnValue(result); | 5744 return ast_context()->ReturnValue(result); |
| 5817 } else { | 5745 } else { |
| 5818 return ast_context()->ReturnValue(Pop()); | 5746 return ast_context()->ReturnValue(Pop()); |
| 5819 } | 5747 } |
| 5820 } | 5748 } |
| 5821 | 5749 |
| 5822 | 5750 |
| 5823 void HOptimizedGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) { | 5751 void HOptimizedGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) { |
| 5824 ASSERT(!HasStackOverflow()); | 5752 ASSERT(!HasStackOverflow()); |
| 5825 ASSERT(current_block() != NULL); | 5753 ASSERT(current_block() != NULL); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5877 data_size, | 5805 data_size, |
| 5878 pointer_size, | 5806 pointer_size, |
| 5879 mode); | 5807 mode); |
| 5880 } else { | 5808 } else { |
| 5881 NoObservableSideEffectsScope no_effects(this); | 5809 NoObservableSideEffectsScope no_effects(this); |
| 5882 // Boilerplate already exists and constant elements are never accessed, | 5810 // Boilerplate already exists and constant elements are never accessed, |
| 5883 // pass an empty fixed array to the runtime function instead. | 5811 // pass an empty fixed array to the runtime function instead. |
| 5884 Handle<FixedArray> constants = isolate()->factory()->empty_fixed_array(); | 5812 Handle<FixedArray> constants = isolate()->factory()->empty_fixed_array(); |
| 5885 int literal_index = expr->literal_index(); | 5813 int literal_index = expr->literal_index(); |
| 5886 | 5814 |
| 5887 AddInstruction(new(zone()) HPushArgument(AddInstruction( | 5815 Add<HPushArgument>(Add<HConstant>(literals)); |
| 5888 new(zone()) HConstant(literals)))); | 5816 Add<HPushArgument>(Add<HConstant>(literal_index)); |
| 5889 AddInstruction(new(zone()) HPushArgument(AddInstruction( | 5817 Add<HPushArgument>(Add<HConstant>(constants)); |
| 5890 new(zone()) HConstant(literal_index)))); | |
| 5891 AddInstruction(new(zone()) HPushArgument(AddInstruction( | |
| 5892 new(zone()) HConstant(constants)))); | |
| 5893 | 5818 |
| 5894 Runtime::FunctionId function_id = (expr->depth() > 1) | 5819 Runtime::FunctionId function_id = (expr->depth() > 1) |
| 5895 ? Runtime::kCreateArrayLiteral : Runtime::kCreateArrayLiteralShallow; | 5820 ? Runtime::kCreateArrayLiteral : Runtime::kCreateArrayLiteralShallow; |
| 5896 literal = AddInstruction( | 5821 literal = Add<HCallRuntime>(context, |
| 5897 new(zone()) HCallRuntime(context, | 5822 isolate()->factory()->empty_string(), |
| 5898 isolate()->factory()->empty_string(), | 5823 Runtime::FunctionForId(function_id), |
| 5899 Runtime::FunctionForId(function_id), | 5824 3); |
| 5900 3)); | |
| 5901 | 5825 |
| 5902 // De-opt if elements kind changed from boilerplate_elements_kind. | 5826 // De-opt if elements kind changed from boilerplate_elements_kind. |
| 5903 Handle<Map> map = Handle<Map>(original_boilerplate_object->map(), | 5827 Handle<Map> map = Handle<Map>(original_boilerplate_object->map(), |
| 5904 isolate()); | 5828 isolate()); |
| 5905 AddInstruction(HCheckMaps::New(literal, map, zone())); | 5829 AddInstruction(HCheckMaps::New(literal, map, zone())); |
| 5906 } | 5830 } |
| 5907 | 5831 |
| 5908 // The array is expected in the bailout environment during computation | 5832 // The array is expected in the bailout environment during computation |
| 5909 // of the property values and is the value of the entire expression. | 5833 // of the property values and is the value of the entire expression. |
| 5910 Push(literal); | 5834 Push(literal); |
| 5911 // The literal index is on the stack, too. | 5835 // The literal index is on the stack, too. |
| 5912 Push(AddInstruction(new(zone()) HConstant(expr->literal_index()))); | 5836 Push(Add<HConstant>(expr->literal_index())); |
| 5913 | 5837 |
| 5914 HInstruction* elements = NULL; | 5838 HInstruction* elements = NULL; |
| 5915 | 5839 |
| 5916 for (int i = 0; i < length; i++) { | 5840 for (int i = 0; i < length; i++) { |
| 5917 Expression* subexpr = subexprs->at(i); | 5841 Expression* subexpr = subexprs->at(i); |
| 5918 // If the subexpression is a literal or a simple materialized literal it | 5842 // If the subexpression is a literal or a simple materialized literal it |
| 5919 // is already set in the cloned array. | 5843 // is already set in the cloned array. |
| 5920 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; | 5844 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; |
| 5921 | 5845 |
| 5922 CHECK_ALIVE(VisitForValue(subexpr)); | 5846 CHECK_ALIVE(VisitForValue(subexpr)); |
| 5923 HValue* value = Pop(); | 5847 HValue* value = Pop(); |
| 5924 if (!Smi::IsValid(i)) return Bailout("Non-smi key in array literal"); | 5848 if (!Smi::IsValid(i)) return Bailout("Non-smi key in array literal"); |
| 5925 | 5849 |
| 5926 elements = AddLoadElements(literal); | 5850 elements = AddLoadElements(literal); |
| 5927 | 5851 |
| 5928 HValue* key = AddInstruction(new(zone()) HConstant(i)); | 5852 HValue* key = Add<HConstant>(i); |
| 5929 | 5853 |
| 5930 switch (boilerplate_elements_kind) { | 5854 switch (boilerplate_elements_kind) { |
| 5931 case FAST_SMI_ELEMENTS: | 5855 case FAST_SMI_ELEMENTS: |
| 5932 case FAST_HOLEY_SMI_ELEMENTS: | 5856 case FAST_HOLEY_SMI_ELEMENTS: |
| 5933 case FAST_ELEMENTS: | 5857 case FAST_ELEMENTS: |
| 5934 case FAST_HOLEY_ELEMENTS: | 5858 case FAST_HOLEY_ELEMENTS: |
| 5935 case FAST_DOUBLE_ELEMENTS: | 5859 case FAST_DOUBLE_ELEMENTS: |
| 5936 case FAST_HOLEY_DOUBLE_ELEMENTS: | 5860 case FAST_HOLEY_DOUBLE_ELEMENTS: |
| 5937 AddInstruction(new(zone()) HStoreKeyed( | 5861 Add<HStoreKeyed>(elements, key, value, |
| 5938 elements, | 5862 boilerplate_elements_kind); |
| 5939 key, | |
| 5940 value, | |
| 5941 boilerplate_elements_kind)); | |
| 5942 break; | 5863 break; |
| 5943 default: | 5864 default: |
| 5944 UNREACHABLE(); | 5865 UNREACHABLE(); |
| 5945 break; | 5866 break; |
| 5946 } | 5867 } |
| 5947 | 5868 |
| 5948 AddSimulate(expr->GetIdForElement(i)); | 5869 AddSimulate(expr->GetIdForElement(i)); |
| 5949 } | 5870 } |
| 5950 | 5871 |
| 5951 Drop(1); // array literal index | 5872 Drop(1); // array literal index |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6028 // We only need to check up to the preexisting property. | 5949 // We only need to check up to the preexisting property. |
| 6029 proto = proto_result.holder(); | 5950 proto = proto_result.holder(); |
| 6030 } else { | 5951 } else { |
| 6031 // Otherwise, find the top prototype. | 5952 // Otherwise, find the top prototype. |
| 6032 while (proto->GetPrototype(isolate())->IsJSObject()) { | 5953 while (proto->GetPrototype(isolate())->IsJSObject()) { |
| 6033 proto = proto->GetPrototype(isolate()); | 5954 proto = proto->GetPrototype(isolate()); |
| 6034 } | 5955 } |
| 6035 ASSERT(proto->GetPrototype(isolate())->IsNull()); | 5956 ASSERT(proto->GetPrototype(isolate())->IsNull()); |
| 6036 } | 5957 } |
| 6037 ASSERT(proto->IsJSObject()); | 5958 ASSERT(proto->IsJSObject()); |
| 6038 AddInstruction(new(zone()) HCheckPrototypeMaps( | 5959 Add<HCheckPrototypeMaps>(Handle<JSObject>(JSObject::cast(map->prototype())), |
| 6039 Handle<JSObject>(JSObject::cast(map->prototype())), | 5960 Handle<JSObject>(JSObject::cast(proto)), |
| 6040 Handle<JSObject>(JSObject::cast(proto)), | 5961 zone(), top_info()); |
| 6041 zone(), | |
| 6042 top_info())); | |
| 6043 } | 5962 } |
| 6044 | 5963 |
| 6045 HObjectAccess field_access = HObjectAccess::ForField(map, lookup, name); | 5964 HObjectAccess field_access = HObjectAccess::ForField(map, lookup, name); |
| 6046 Representation representation = ComputeLoadStoreRepresentation(map, lookup); | 5965 Representation representation = ComputeLoadStoreRepresentation(map, lookup); |
| 6047 bool transition_to_field = lookup->IsTransitionToField(*map); | 5966 bool transition_to_field = lookup->IsTransitionToField(*map); |
| 6048 | 5967 |
| 6049 HStoreNamedField *instr; | 5968 HStoreNamedField *instr; |
| 6050 if (FLAG_track_double_fields && representation.IsDouble()) { | 5969 if (FLAG_track_double_fields && representation.IsDouble()) { |
| 6051 if (transition_to_field) { | 5970 if (transition_to_field) { |
| 6052 // The store requires a mutable HeapNumber to be allocated. | 5971 // The store requires a mutable HeapNumber to be allocated. |
| 6053 NoObservableSideEffectsScope no_side_effects(this); | 5972 NoObservableSideEffectsScope no_side_effects(this); |
| 6054 HInstruction* heap_number_size = AddInstruction(new(zone()) HConstant( | 5973 HInstruction* heap_number_size = Add<HConstant>(HeapNumber::kSize); |
| 6055 HeapNumber::kSize)); | 5974 HInstruction* double_box = Add<HAllocate>( |
| 6056 HInstruction* double_box = AddInstruction(new(zone()) HAllocate( | |
| 6057 environment()->LookupContext(), heap_number_size, | 5975 environment()->LookupContext(), heap_number_size, |
| 6058 HType::HeapNumber(), HAllocate::CAN_ALLOCATE_IN_NEW_SPACE)); | 5976 HType::HeapNumber(), HAllocate::CAN_ALLOCATE_IN_NEW_SPACE); |
| 6059 AddStoreMapConstant(double_box, isolate()->factory()->heap_number_map()); | 5977 AddStoreMapConstant(double_box, isolate()->factory()->heap_number_map()); |
| 6060 AddStore(double_box, HObjectAccess::ForHeapNumberValue(), | 5978 AddStore(double_box, HObjectAccess::ForHeapNumberValue(), |
| 6061 value, Representation::Double()); | 5979 value, Representation::Double()); |
| 6062 instr = new(zone()) HStoreNamedField(object, field_access, double_box); | 5980 instr = new(zone()) HStoreNamedField(object, field_access, double_box); |
| 6063 } else { | 5981 } else { |
| 6064 // Already holds a HeapNumber; load the box and write its value field. | 5982 // Already holds a HeapNumber; load the box and write its value field. |
| 6065 HInstruction* double_box = AddLoad(object, field_access); | 5983 HInstruction* double_box = AddLoad(object, field_access); |
| 6066 double_box->set_type(HType::HeapNumber()); | 5984 double_box->set_type(HType::HeapNumber()); |
| 6067 instr = new(zone()) HStoreNamedField(double_box, | 5985 instr = new(zone()) HStoreNamedField(double_box, |
| 6068 HObjectAccess::ForHeapNumberValue(), value, Representation::Double()); | 5986 HObjectAccess::ForHeapNumberValue(), value, Representation::Double()); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 6098 } | 6016 } |
| 6099 | 6017 |
| 6100 | 6018 |
| 6101 HInstruction* HOptimizedGraphBuilder::BuildCallSetter( | 6019 HInstruction* HOptimizedGraphBuilder::BuildCallSetter( |
| 6102 HValue* object, | 6020 HValue* object, |
| 6103 HValue* value, | 6021 HValue* value, |
| 6104 Handle<Map> map, | 6022 Handle<Map> map, |
| 6105 Handle<JSFunction> setter, | 6023 Handle<JSFunction> setter, |
| 6106 Handle<JSObject> holder) { | 6024 Handle<JSObject> holder) { |
| 6107 AddCheckConstantFunction(holder, object, map); | 6025 AddCheckConstantFunction(holder, object, map); |
| 6108 AddInstruction(new(zone()) HPushArgument(object)); | 6026 Add<HPushArgument>(object); |
| 6109 AddInstruction(new(zone()) HPushArgument(value)); | 6027 Add<HPushArgument>(value); |
| 6110 return new(zone()) HCallConstantFunction(setter, 2); | 6028 return new(zone()) HCallConstantFunction(setter, 2); |
| 6111 } | 6029 } |
| 6112 | 6030 |
| 6113 | 6031 |
| 6114 HInstruction* HOptimizedGraphBuilder::BuildStoreNamedMonomorphic( | 6032 HInstruction* HOptimizedGraphBuilder::BuildStoreNamedMonomorphic( |
| 6115 HValue* object, | 6033 HValue* object, |
| 6116 Handle<String> name, | 6034 Handle<String> name, |
| 6117 HValue* value, | 6035 HValue* value, |
| 6118 Handle<Map> map) { | 6036 Handle<Map> map) { |
| 6119 // Handle a store to a known field. | 6037 // Handle a store to a known field. |
| (...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6379 void HOptimizedGraphBuilder::HandleGlobalVariableAssignment( | 6297 void HOptimizedGraphBuilder::HandleGlobalVariableAssignment( |
| 6380 Variable* var, | 6298 Variable* var, |
| 6381 HValue* value, | 6299 HValue* value, |
| 6382 int position, | 6300 int position, |
| 6383 BailoutId ast_id) { | 6301 BailoutId ast_id) { |
| 6384 LookupResult lookup(isolate()); | 6302 LookupResult lookup(isolate()); |
| 6385 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, true); | 6303 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, true); |
| 6386 if (type == kUseCell) { | 6304 if (type == kUseCell) { |
| 6387 Handle<GlobalObject> global(current_info()->global_object()); | 6305 Handle<GlobalObject> global(current_info()->global_object()); |
| 6388 Handle<PropertyCell> cell(global->GetPropertyCell(&lookup)); | 6306 Handle<PropertyCell> cell(global->GetPropertyCell(&lookup)); |
| 6389 HInstruction* instr = | 6307 HInstruction* instr = Add<HStoreGlobalCell>(value, cell, |
| 6390 new(zone()) HStoreGlobalCell(value, cell, lookup.GetPropertyDetails()); | 6308 lookup.GetPropertyDetails()); |
| 6391 instr->set_position(position); | 6309 instr->set_position(position); |
| 6392 AddInstruction(instr); | |
| 6393 if (instr->HasObservableSideEffects()) { | 6310 if (instr->HasObservableSideEffects()) { |
| 6394 AddSimulate(ast_id, REMOVABLE_SIMULATE); | 6311 AddSimulate(ast_id, REMOVABLE_SIMULATE); |
| 6395 } | 6312 } |
| 6396 } else { | 6313 } else { |
| 6397 HValue* context = environment()->LookupContext(); | 6314 HValue* context = environment()->LookupContext(); |
| 6398 HGlobalObject* global_object = new(zone()) HGlobalObject(context); | 6315 HGlobalObject* global_object = Add<HGlobalObject>(context); |
| 6399 AddInstruction(global_object); | |
| 6400 HStoreGlobalGeneric* instr = | 6316 HStoreGlobalGeneric* instr = |
| 6401 new(zone()) HStoreGlobalGeneric(context, | 6317 Add<HStoreGlobalGeneric>(context, global_object, var->name(), |
| 6402 global_object, | 6318 value, function_strict_mode_flag()); |
| 6403 var->name(), | |
| 6404 value, | |
| 6405 function_strict_mode_flag()); | |
| 6406 instr->set_position(position); | 6319 instr->set_position(position); |
| 6407 AddInstruction(instr); | |
| 6408 ASSERT(instr->HasObservableSideEffects()); | 6320 ASSERT(instr->HasObservableSideEffects()); |
| 6409 AddSimulate(ast_id, REMOVABLE_SIMULATE); | 6321 AddSimulate(ast_id, REMOVABLE_SIMULATE); |
| 6410 } | 6322 } |
| 6411 } | 6323 } |
| 6412 | 6324 |
| 6413 | 6325 |
| 6414 void HOptimizedGraphBuilder::BuildStoreNamed(Expression* expr, | 6326 void HOptimizedGraphBuilder::BuildStoreNamed(Expression* expr, |
| 6415 BailoutId id, | 6327 BailoutId id, |
| 6416 int position, | 6328 int position, |
| 6417 BailoutId assignment_id, | 6329 BailoutId assignment_id, |
| (...skipping 15 matching lines...) Expand all Loading... |
| 6433 if (monomorphic) { | 6345 if (monomorphic) { |
| 6434 Handle<JSFunction> setter; | 6346 Handle<JSFunction> setter; |
| 6435 Handle<JSObject> holder; | 6347 Handle<JSObject> holder; |
| 6436 if (LookupSetter(map, name, &setter, &holder)) { | 6348 if (LookupSetter(map, name, &setter, &holder)) { |
| 6437 AddCheckConstantFunction(holder, object, map); | 6349 AddCheckConstantFunction(holder, object, map); |
| 6438 if (FLAG_inline_accessors && | 6350 if (FLAG_inline_accessors && |
| 6439 TryInlineSetter(setter, id, assignment_id, value)) { | 6351 TryInlineSetter(setter, id, assignment_id, value)) { |
| 6440 return; | 6352 return; |
| 6441 } | 6353 } |
| 6442 Drop(2); | 6354 Drop(2); |
| 6443 AddInstruction(new(zone()) HPushArgument(object)); | 6355 Add<HPushArgument>(object); |
| 6444 AddInstruction(new(zone()) HPushArgument(value)); | 6356 Add<HPushArgument>(value); |
| 6445 instr = new(zone()) HCallConstantFunction(setter, 2); | 6357 instr = new(zone()) HCallConstantFunction(setter, 2); |
| 6446 } else { | 6358 } else { |
| 6447 Drop(2); | 6359 Drop(2); |
| 6448 CHECK_ALIVE(instr = BuildStoreNamedMonomorphic(object, | 6360 CHECK_ALIVE(instr = BuildStoreNamedMonomorphic(object, |
| 6449 name, | 6361 name, |
| 6450 value, | 6362 value, |
| 6451 map)); | 6363 map)); |
| 6452 } | 6364 } |
| 6453 | 6365 |
| 6454 } else if (types != NULL && types->length() > 1) { | 6366 } else if (types != NULL && types->length() > 1) { |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6531 return ast_context()->ReturnValue(Pop()); | 6443 return ast_context()->ReturnValue(Pop()); |
| 6532 case CONST_HARMONY: | 6444 case CONST_HARMONY: |
| 6533 // This case is checked statically so no need to | 6445 // This case is checked statically so no need to |
| 6534 // perform checks here | 6446 // perform checks here |
| 6535 UNREACHABLE(); | 6447 UNREACHABLE(); |
| 6536 default: | 6448 default: |
| 6537 mode = HStoreContextSlot::kNoCheck; | 6449 mode = HStoreContextSlot::kNoCheck; |
| 6538 } | 6450 } |
| 6539 | 6451 |
| 6540 HValue* context = BuildContextChainWalk(var); | 6452 HValue* context = BuildContextChainWalk(var); |
| 6541 HStoreContextSlot* instr = | 6453 HStoreContextSlot* instr = Add<HStoreContextSlot>(context, var->index(), |
| 6542 new(zone()) HStoreContextSlot(context, var->index(), mode, Top()); | 6454 mode, Top()); |
| 6543 AddInstruction(instr); | |
| 6544 if (instr->HasObservableSideEffects()) { | 6455 if (instr->HasObservableSideEffects()) { |
| 6545 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE); | 6456 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE); |
| 6546 } | 6457 } |
| 6547 break; | 6458 break; |
| 6548 } | 6459 } |
| 6549 | 6460 |
| 6550 case Variable::LOOKUP: | 6461 case Variable::LOOKUP: |
| 6551 return Bailout("compound assignment to lookup slot"); | 6462 return Bailout("compound assignment to lookup slot"); |
| 6552 } | 6463 } |
| 6553 return ast_context()->ReturnValue(Pop()); | 6464 return ast_context()->ReturnValue(Pop()); |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6663 if (var->mode() == CONST) { | 6574 if (var->mode() == CONST) { |
| 6664 if (expr->op() != Token::INIT_CONST) { | 6575 if (expr->op() != Token::INIT_CONST) { |
| 6665 CHECK_ALIVE(VisitForValue(expr->value())); | 6576 CHECK_ALIVE(VisitForValue(expr->value())); |
| 6666 return ast_context()->ReturnValue(Pop()); | 6577 return ast_context()->ReturnValue(Pop()); |
| 6667 } | 6578 } |
| 6668 | 6579 |
| 6669 if (var->IsStackAllocated()) { | 6580 if (var->IsStackAllocated()) { |
| 6670 // We insert a use of the old value to detect unsupported uses of const | 6581 // We insert a use of the old value to detect unsupported uses of const |
| 6671 // variables (e.g. initialization inside a loop). | 6582 // variables (e.g. initialization inside a loop). |
| 6672 HValue* old_value = environment()->Lookup(var); | 6583 HValue* old_value = environment()->Lookup(var); |
| 6673 AddInstruction(new(zone()) HUseConst(old_value)); | 6584 Add<HUseConst>(old_value); |
| 6674 } | 6585 } |
| 6675 } else if (var->mode() == CONST_HARMONY) { | 6586 } else if (var->mode() == CONST_HARMONY) { |
| 6676 if (expr->op() != Token::INIT_CONST_HARMONY) { | 6587 if (expr->op() != Token::INIT_CONST_HARMONY) { |
| 6677 return Bailout("non-initializer assignment to const"); | 6588 return Bailout("non-initializer assignment to const"); |
| 6678 } | 6589 } |
| 6679 } | 6590 } |
| 6680 | 6591 |
| 6681 if (proxy->IsArguments()) return Bailout("assignment to arguments"); | 6592 if (proxy->IsArguments()) return Bailout("assignment to arguments"); |
| 6682 | 6593 |
| 6683 // Handle the assignment. | 6594 // Handle the assignment. |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6744 expr->op() == Token::INIT_LET || | 6655 expr->op() == Token::INIT_LET || |
| 6745 expr->op() == Token::INIT_CONST_HARMONY) { | 6656 expr->op() == Token::INIT_CONST_HARMONY) { |
| 6746 mode = HStoreContextSlot::kNoCheck; | 6657 mode = HStoreContextSlot::kNoCheck; |
| 6747 } else { | 6658 } else { |
| 6748 ASSERT(expr->op() == Token::INIT_CONST); | 6659 ASSERT(expr->op() == Token::INIT_CONST); |
| 6749 | 6660 |
| 6750 mode = HStoreContextSlot::kCheckIgnoreAssignment; | 6661 mode = HStoreContextSlot::kCheckIgnoreAssignment; |
| 6751 } | 6662 } |
| 6752 | 6663 |
| 6753 HValue* context = BuildContextChainWalk(var); | 6664 HValue* context = BuildContextChainWalk(var); |
| 6754 HStoreContextSlot* instr = new(zone()) HStoreContextSlot( | 6665 HStoreContextSlot* instr = Add<HStoreContextSlot>(context, var->index(), |
| 6755 context, var->index(), mode, Top()); | 6666 mode, Top()); |
| 6756 AddInstruction(instr); | |
| 6757 if (instr->HasObservableSideEffects()) { | 6667 if (instr->HasObservableSideEffects()) { |
| 6758 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE); | 6668 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE); |
| 6759 } | 6669 } |
| 6760 return ast_context()->ReturnValue(Pop()); | 6670 return ast_context()->ReturnValue(Pop()); |
| 6761 } | 6671 } |
| 6762 | 6672 |
| 6763 case Variable::LOOKUP: | 6673 case Variable::LOOKUP: |
| 6764 return Bailout("assignment to LOOKUP variable"); | 6674 return Bailout("assignment to LOOKUP variable"); |
| 6765 } | 6675 } |
| 6766 } else { | 6676 } else { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 6780 ASSERT(current_block() != NULL); | 6690 ASSERT(current_block() != NULL); |
| 6781 ASSERT(current_block()->HasPredecessor()); | 6691 ASSERT(current_block()->HasPredecessor()); |
| 6782 // We don't optimize functions with invalid left-hand sides in | 6692 // We don't optimize functions with invalid left-hand sides in |
| 6783 // assignments, count operations, or for-in. Consequently throw can | 6693 // assignments, count operations, or for-in. Consequently throw can |
| 6784 // currently only occur in an effect context. | 6694 // currently only occur in an effect context. |
| 6785 ASSERT(ast_context()->IsEffect()); | 6695 ASSERT(ast_context()->IsEffect()); |
| 6786 CHECK_ALIVE(VisitForValue(expr->exception())); | 6696 CHECK_ALIVE(VisitForValue(expr->exception())); |
| 6787 | 6697 |
| 6788 HValue* context = environment()->LookupContext(); | 6698 HValue* context = environment()->LookupContext(); |
| 6789 HValue* value = environment()->Pop(); | 6699 HValue* value = environment()->Pop(); |
| 6790 HThrow* instr = new(zone()) HThrow(context, value); | 6700 HThrow* instr = Add<HThrow>(context, value); |
| 6791 instr->set_position(expr->position()); | 6701 instr->set_position(expr->position()); |
| 6792 AddInstruction(instr); | |
| 6793 AddSimulate(expr->id()); | 6702 AddSimulate(expr->id()); |
| 6794 current_block()->FinishExit(new(zone()) HAbnormalExit); | 6703 current_block()->FinishExit(new(zone()) HAbnormalExit); |
| 6795 set_current_block(NULL); | 6704 set_current_block(NULL); |
| 6796 } | 6705 } |
| 6797 | 6706 |
| 6798 | 6707 |
| 6799 HLoadNamedField* HGraphBuilder::BuildLoadNamedField( | 6708 HLoadNamedField* HGraphBuilder::BuildLoadNamedField( |
| 6800 HValue* object, | 6709 HValue* object, |
| 6801 HObjectAccess access, | 6710 HObjectAccess access, |
| 6802 Representation representation) { | 6711 Representation representation) { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 6828 return new(zone()) HLoadNamedGeneric(context, object, name); | 6737 return new(zone()) HLoadNamedGeneric(context, object, name); |
| 6829 } | 6738 } |
| 6830 | 6739 |
| 6831 | 6740 |
| 6832 HInstruction* HOptimizedGraphBuilder::BuildCallGetter( | 6741 HInstruction* HOptimizedGraphBuilder::BuildCallGetter( |
| 6833 HValue* object, | 6742 HValue* object, |
| 6834 Handle<Map> map, | 6743 Handle<Map> map, |
| 6835 Handle<JSFunction> getter, | 6744 Handle<JSFunction> getter, |
| 6836 Handle<JSObject> holder) { | 6745 Handle<JSObject> holder) { |
| 6837 AddCheckConstantFunction(holder, object, map); | 6746 AddCheckConstantFunction(holder, object, map); |
| 6838 AddInstruction(new(zone()) HPushArgument(object)); | 6747 Add<HPushArgument>(object); |
| 6839 return new(zone()) HCallConstantFunction(getter, 1); | 6748 return new(zone()) HCallConstantFunction(getter, 1); |
| 6840 } | 6749 } |
| 6841 | 6750 |
| 6842 | 6751 |
| 6843 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedMonomorphic( | 6752 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedMonomorphic( |
| 6844 HValue* object, | 6753 HValue* object, |
| 6845 Handle<String> name, | 6754 Handle<String> name, |
| 6846 Property* expr, | 6755 Property* expr, |
| 6847 Handle<Map> map) { | 6756 Handle<Map> map) { |
| 6848 // Handle a load from a known field. | 6757 // Handle a load from a known field. |
| (...skipping 24 matching lines...) Expand all Loading... |
| 6873 return new(zone()) HConstant(function); | 6782 return new(zone()) HConstant(function); |
| 6874 } | 6783 } |
| 6875 | 6784 |
| 6876 // Handle a load from a known field somewhere in the prototype chain. | 6785 // Handle a load from a known field somewhere in the prototype chain. |
| 6877 LookupInPrototypes(map, name, &lookup); | 6786 LookupInPrototypes(map, name, &lookup); |
| 6878 if (lookup.IsField()) { | 6787 if (lookup.IsField()) { |
| 6879 Handle<JSObject> prototype(JSObject::cast(map->prototype())); | 6788 Handle<JSObject> prototype(JSObject::cast(map->prototype())); |
| 6880 Handle<JSObject> holder(lookup.holder()); | 6789 Handle<JSObject> holder(lookup.holder()); |
| 6881 Handle<Map> holder_map(holder->map()); | 6790 Handle<Map> holder_map(holder->map()); |
| 6882 AddCheckMap(object, map); | 6791 AddCheckMap(object, map); |
| 6883 AddInstruction(new(zone()) HCheckPrototypeMaps( | 6792 Add<HCheckPrototypeMaps>(prototype, holder, zone(), top_info()); |
| 6884 prototype, holder, zone(), top_info())); | 6793 HValue* holder_value = Add<HConstant>(holder); |
| 6885 HValue* holder_value = AddInstruction(new(zone()) HConstant(holder)); | |
| 6886 return BuildLoadNamedField(holder_value, | 6794 return BuildLoadNamedField(holder_value, |
| 6887 HObjectAccess::ForField(holder_map, &lookup, name), | 6795 HObjectAccess::ForField(holder_map, &lookup, name), |
| 6888 ComputeLoadStoreRepresentation(map, &lookup)); | 6796 ComputeLoadStoreRepresentation(map, &lookup)); |
| 6889 } | 6797 } |
| 6890 | 6798 |
| 6891 // Handle a load of a constant function somewhere in the prototype chain. | 6799 // Handle a load of a constant function somewhere in the prototype chain. |
| 6892 if (lookup.IsConstantFunction()) { | 6800 if (lookup.IsConstantFunction()) { |
| 6893 Handle<JSObject> prototype(JSObject::cast(map->prototype())); | 6801 Handle<JSObject> prototype(JSObject::cast(map->prototype())); |
| 6894 Handle<JSObject> holder(lookup.holder()); | 6802 Handle<JSObject> holder(lookup.holder()); |
| 6895 Handle<Map> holder_map(holder->map()); | 6803 Handle<Map> holder_map(holder->map()); |
| 6896 AddCheckMap(object, map); | 6804 AddCheckMap(object, map); |
| 6897 AddInstruction(new(zone()) HCheckPrototypeMaps( | 6805 Add<HCheckPrototypeMaps>(prototype, holder, zone(), top_info()); |
| 6898 prototype, holder, zone(), top_info())); | |
| 6899 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*holder_map)); | 6806 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*holder_map)); |
| 6900 return new(zone()) HConstant(function); | 6807 return new(zone()) HConstant(function); |
| 6901 } | 6808 } |
| 6902 | 6809 |
| 6903 // No luck, do a generic load. | 6810 // No luck, do a generic load. |
| 6904 return BuildLoadNamedGeneric(object, name, expr); | 6811 return BuildLoadNamedGeneric(object, name, expr); |
| 6905 } | 6812 } |
| 6906 | 6813 |
| 6907 | 6814 |
| 6908 HInstruction* HOptimizedGraphBuilder::BuildLoadKeyedGeneric(HValue* object, | 6815 HInstruction* HOptimizedGraphBuilder::BuildLoadKeyedGeneric(HValue* object, |
| (...skipping 16 matching lines...) Expand all Loading... |
| 6925 if (dependency) { | 6832 if (dependency) { |
| 6926 mapcheck->ClearGVNFlag(kDependsOnElementsKind); | 6833 mapcheck->ClearGVNFlag(kDependsOnElementsKind); |
| 6927 } | 6834 } |
| 6928 | 6835 |
| 6929 // Loads from a "stock" fast holey double arrays can elide the hole check. | 6836 // Loads from a "stock" fast holey double arrays can elide the hole check. |
| 6930 LoadKeyedHoleMode load_mode = NEVER_RETURN_HOLE; | 6837 LoadKeyedHoleMode load_mode = NEVER_RETURN_HOLE; |
| 6931 if (*map == isolate()->get_initial_js_array_map(FAST_HOLEY_DOUBLE_ELEMENTS) && | 6838 if (*map == isolate()->get_initial_js_array_map(FAST_HOLEY_DOUBLE_ELEMENTS) && |
| 6932 isolate()->IsFastArrayConstructorPrototypeChainIntact()) { | 6839 isolate()->IsFastArrayConstructorPrototypeChainIntact()) { |
| 6933 Handle<JSObject> prototype(JSObject::cast(map->prototype()), isolate()); | 6840 Handle<JSObject> prototype(JSObject::cast(map->prototype()), isolate()); |
| 6934 Handle<JSObject> object_prototype = isolate()->initial_object_prototype(); | 6841 Handle<JSObject> object_prototype = isolate()->initial_object_prototype(); |
| 6935 AddInstruction(new(zone()) HCheckPrototypeMaps( | 6842 Add<HCheckPrototypeMaps>(prototype, object_prototype, zone(), top_info()); |
| 6936 prototype, object_prototype, zone(), top_info())); | |
| 6937 load_mode = ALLOW_RETURN_HOLE; | 6843 load_mode = ALLOW_RETURN_HOLE; |
| 6938 graph()->MarkDependsOnEmptyArrayProtoElements(); | 6844 graph()->MarkDependsOnEmptyArrayProtoElements(); |
| 6939 } | 6845 } |
| 6940 | 6846 |
| 6941 return BuildUncheckedMonomorphicElementAccess( | 6847 return BuildUncheckedMonomorphicElementAccess( |
| 6942 object, key, val, | 6848 object, key, val, |
| 6943 mapcheck, map->instance_type() == JS_ARRAY_TYPE, | 6849 mapcheck, map->instance_type() == JS_ARRAY_TYPE, |
| 6944 map->elements_kind(), is_store, load_mode, store_mode); | 6850 map->elements_kind(), is_store, load_mode, store_mode); |
| 6945 } | 6851 } |
| 6946 | 6852 |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7058 Handle<Map> untransitionable_map; | 6964 Handle<Map> untransitionable_map; |
| 7059 HTransitionElementsKind* transition = NULL; | 6965 HTransitionElementsKind* transition = NULL; |
| 7060 for (int i = 0; i < maps->length(); ++i) { | 6966 for (int i = 0; i < maps->length(); ++i) { |
| 7061 Handle<Map> map = maps->at(i); | 6967 Handle<Map> map = maps->at(i); |
| 7062 ASSERT(map->IsMap()); | 6968 ASSERT(map->IsMap()); |
| 7063 if (!transition_target.at(i).is_null()) { | 6969 if (!transition_target.at(i).is_null()) { |
| 7064 ASSERT(Map::IsValidElementsTransition( | 6970 ASSERT(Map::IsValidElementsTransition( |
| 7065 map->elements_kind(), | 6971 map->elements_kind(), |
| 7066 transition_target.at(i)->elements_kind())); | 6972 transition_target.at(i)->elements_kind())); |
| 7067 HValue* context = environment()->LookupContext(); | 6973 HValue* context = environment()->LookupContext(); |
| 7068 transition = new(zone()) HTransitionElementsKind( | 6974 transition = Add<HTransitionElementsKind>(context, object, map, |
| 7069 context, object, map, transition_target.at(i)); | 6975 transition_target.at(i)); |
| 7070 AddInstruction(transition); | |
| 7071 } else { | 6976 } else { |
| 7072 type_todo[map->elements_kind()] = true; | 6977 type_todo[map->elements_kind()] = true; |
| 7073 if (IsExternalArrayElementsKind(map->elements_kind())) { | 6978 if (IsExternalArrayElementsKind(map->elements_kind())) { |
| 7074 todo_external_array = true; | 6979 todo_external_array = true; |
| 7075 } | 6980 } |
| 7076 num_untransitionable_maps++; | 6981 num_untransitionable_maps++; |
| 7077 untransitionable_map = map; | 6982 untransitionable_map = map; |
| 7078 } | 6983 } |
| 7079 } | 6984 } |
| 7080 | 6985 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 7093 } | 6998 } |
| 7094 *has_side_effects |= instr->HasObservableSideEffects(); | 6999 *has_side_effects |= instr->HasObservableSideEffects(); |
| 7095 if (position != RelocInfo::kNoPosition) instr->set_position(position); | 7000 if (position != RelocInfo::kNoPosition) instr->set_position(position); |
| 7096 return is_store ? NULL : instr; | 7001 return is_store ? NULL : instr; |
| 7097 } | 7002 } |
| 7098 | 7003 |
| 7099 HInstruction* checkspec = | 7004 HInstruction* checkspec = |
| 7100 AddInstruction(HCheckInstanceType::NewIsSpecObject(object, zone())); | 7005 AddInstruction(HCheckInstanceType::NewIsSpecObject(object, zone())); |
| 7101 HBasicBlock* join = graph()->CreateBasicBlock(); | 7006 HBasicBlock* join = graph()->CreateBasicBlock(); |
| 7102 | 7007 |
| 7103 HInstruction* elements_kind_instr = | 7008 HInstruction* elements_kind_instr = Add<HElementsKind>(object); |
| 7104 AddInstruction(new(zone()) HElementsKind(object)); | |
| 7105 HInstruction* elements = AddLoadElements(object, checkspec); | 7009 HInstruction* elements = AddLoadElements(object, checkspec); |
| 7106 HLoadExternalArrayPointer* external_elements = NULL; | 7010 HLoadExternalArrayPointer* external_elements = NULL; |
| 7107 HInstruction* checked_key = NULL; | 7011 HInstruction* checked_key = NULL; |
| 7108 | 7012 |
| 7109 // Generated code assumes that FAST_* and DICTIONARY_ELEMENTS ElementsKinds | 7013 // Generated code assumes that FAST_* and DICTIONARY_ELEMENTS ElementsKinds |
| 7110 // are handled before external arrays. | 7014 // are handled before external arrays. |
| 7111 STATIC_ASSERT(FAST_SMI_ELEMENTS < FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND); | 7015 STATIC_ASSERT(FAST_SMI_ELEMENTS < FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND); |
| 7112 STATIC_ASSERT(FAST_HOLEY_ELEMENTS < FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND); | 7016 STATIC_ASSERT(FAST_HOLEY_ELEMENTS < FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND); |
| 7113 STATIC_ASSERT(FAST_DOUBLE_ELEMENTS < FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND); | 7017 STATIC_ASSERT(FAST_DOUBLE_ELEMENTS < FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND); |
| 7114 STATIC_ASSERT(DICTIONARY_ELEMENTS < FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND); | 7018 STATIC_ASSERT(DICTIONARY_ELEMENTS < FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND); |
| 7115 | 7019 |
| 7116 for (ElementsKind elements_kind = FIRST_ELEMENTS_KIND; | 7020 for (ElementsKind elements_kind = FIRST_ELEMENTS_KIND; |
| 7117 elements_kind <= LAST_ELEMENTS_KIND; | 7021 elements_kind <= LAST_ELEMENTS_KIND; |
| 7118 elements_kind = ElementsKind(elements_kind + 1)) { | 7022 elements_kind = ElementsKind(elements_kind + 1)) { |
| 7119 // After having handled FAST_* and DICTIONARY_ELEMENTS, we need to add some | 7023 // After having handled FAST_* and DICTIONARY_ELEMENTS, we need to add some |
| 7120 // code that's executed for all external array cases. | 7024 // code that's executed for all external array cases. |
| 7121 STATIC_ASSERT(LAST_EXTERNAL_ARRAY_ELEMENTS_KIND == | 7025 STATIC_ASSERT(LAST_EXTERNAL_ARRAY_ELEMENTS_KIND == |
| 7122 LAST_ELEMENTS_KIND); | 7026 LAST_ELEMENTS_KIND); |
| 7123 if (elements_kind == FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND | 7027 if (elements_kind == FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND |
| 7124 && todo_external_array) { | 7028 && todo_external_array) { |
| 7125 HInstruction* length = | 7029 HInstruction* length = Add<HFixedArrayBaseLength>(elements); |
| 7126 AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); | |
| 7127 checked_key = Add<HBoundsCheck>(key, length); | 7030 checked_key = Add<HBoundsCheck>(key, length); |
| 7128 external_elements = new(zone()) HLoadExternalArrayPointer(elements); | 7031 external_elements = Add<HLoadExternalArrayPointer>(elements); |
| 7129 AddInstruction(external_elements); | |
| 7130 } | 7032 } |
| 7131 if (type_todo[elements_kind]) { | 7033 if (type_todo[elements_kind]) { |
| 7132 HBasicBlock* if_true = graph()->CreateBasicBlock(); | 7034 HBasicBlock* if_true = graph()->CreateBasicBlock(); |
| 7133 HBasicBlock* if_false = graph()->CreateBasicBlock(); | 7035 HBasicBlock* if_false = graph()->CreateBasicBlock(); |
| 7134 HCompareConstantEqAndBranch* elements_kind_branch = | 7036 HCompareConstantEqAndBranch* elements_kind_branch = |
| 7135 new(zone()) HCompareConstantEqAndBranch( | 7037 new(zone()) HCompareConstantEqAndBranch( |
| 7136 elements_kind_instr, elements_kind, Token::EQ_STRICT); | 7038 elements_kind_instr, elements_kind, Token::EQ_STRICT); |
| 7137 elements_kind_branch->SetSuccessorAt(0, if_true); | 7039 elements_kind_branch->SetSuccessorAt(0, if_true); |
| 7138 elements_kind_branch->SetSuccessorAt(1, if_false); | 7040 elements_kind_branch->SetSuccessorAt(1, if_false); |
| 7139 current_block()->Finish(elements_kind_branch); | 7041 current_block()->Finish(elements_kind_branch); |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7310 if (!environment()->Lookup(proxy->var())->CheckFlag(HValue::kIsArguments)) { | 7212 if (!environment()->Lookup(proxy->var())->CheckFlag(HValue::kIsArguments)) { |
| 7311 return false; | 7213 return false; |
| 7312 } | 7214 } |
| 7313 | 7215 |
| 7314 HInstruction* result = NULL; | 7216 HInstruction* result = NULL; |
| 7315 if (expr->key()->IsPropertyName()) { | 7217 if (expr->key()->IsPropertyName()) { |
| 7316 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); | 7218 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); |
| 7317 if (!name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("length"))) return false; | 7219 if (!name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("length"))) return false; |
| 7318 | 7220 |
| 7319 if (function_state()->outer() == NULL) { | 7221 if (function_state()->outer() == NULL) { |
| 7320 HInstruction* elements = AddInstruction( | 7222 HInstruction* elements = Add<HArgumentsElements>(false); |
| 7321 new(zone()) HArgumentsElements(false)); | |
| 7322 result = new(zone()) HArgumentsLength(elements); | 7223 result = new(zone()) HArgumentsLength(elements); |
| 7323 } else { | 7224 } else { |
| 7324 // Number of arguments without receiver. | 7225 // Number of arguments without receiver. |
| 7325 int argument_count = environment()-> | 7226 int argument_count = environment()-> |
| 7326 arguments_environment()->parameter_count() - 1; | 7227 arguments_environment()->parameter_count() - 1; |
| 7327 result = new(zone()) HConstant(argument_count); | 7228 result = new(zone()) HConstant(argument_count); |
| 7328 } | 7229 } |
| 7329 } else { | 7230 } else { |
| 7330 Push(graph()->GetArgumentsObject()); | 7231 Push(graph()->GetArgumentsObject()); |
| 7331 VisitForValue(expr->key()); | 7232 VisitForValue(expr->key()); |
| 7332 if (HasStackOverflow() || current_block() == NULL) return true; | 7233 if (HasStackOverflow() || current_block() == NULL) return true; |
| 7333 HValue* key = Pop(); | 7234 HValue* key = Pop(); |
| 7334 Drop(1); // Arguments object. | 7235 Drop(1); // Arguments object. |
| 7335 if (function_state()->outer() == NULL) { | 7236 if (function_state()->outer() == NULL) { |
| 7336 HInstruction* elements = AddInstruction( | 7237 HInstruction* elements = Add<HArgumentsElements>(false); |
| 7337 new(zone()) HArgumentsElements(false)); | 7238 HInstruction* length = Add<HArgumentsLength>(elements); |
| 7338 HInstruction* length = AddInstruction( | |
| 7339 new(zone()) HArgumentsLength(elements)); | |
| 7340 HInstruction* checked_key = Add<HBoundsCheck>(key, length); | 7239 HInstruction* checked_key = Add<HBoundsCheck>(key, length); |
| 7341 result = new(zone()) HAccessArgumentsAt(elements, length, checked_key); | 7240 result = new(zone()) HAccessArgumentsAt(elements, length, checked_key); |
| 7342 } else { | 7241 } else { |
| 7343 EnsureArgumentsArePushedForAccess(); | 7242 EnsureArgumentsArePushedForAccess(); |
| 7344 | 7243 |
| 7345 // Number of arguments without receiver. | 7244 // Number of arguments without receiver. |
| 7346 HInstruction* elements = function_state()->arguments_elements(); | 7245 HInstruction* elements = function_state()->arguments_elements(); |
| 7347 int argument_count = environment()-> | 7246 int argument_count = environment()-> |
| 7348 arguments_environment()->parameter_count() - 1; | 7247 arguments_environment()->parameter_count() - 1; |
| 7349 HInstruction* length = AddInstruction(new(zone()) HConstant( | 7248 HInstruction* length = Add<HConstant>(argument_count); |
| 7350 argument_count)); | |
| 7351 HInstruction* checked_key = Add<HBoundsCheck>(key, length); | 7249 HInstruction* checked_key = Add<HBoundsCheck>(key, length); |
| 7352 result = new(zone()) HAccessArgumentsAt(elements, length, checked_key); | 7250 result = new(zone()) HAccessArgumentsAt(elements, length, checked_key); |
| 7353 } | 7251 } |
| 7354 } | 7252 } |
| 7355 ast_context()->ReturnInstruction(result, expr->id()); | 7253 ast_context()->ReturnInstruction(result, expr->id()); |
| 7356 return true; | 7254 return true; |
| 7357 } | 7255 } |
| 7358 | 7256 |
| 7359 | 7257 |
| 7360 void HOptimizedGraphBuilder::VisitProperty(Property* expr) { | 7258 void HOptimizedGraphBuilder::VisitProperty(Property* expr) { |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7400 } else if (object->HasMonomorphicJSObjectType()) { | 7298 } else if (object->HasMonomorphicJSObjectType()) { |
| 7401 map = object->GetMonomorphicJSObjectMap(); | 7299 map = object->GetMonomorphicJSObjectMap(); |
| 7402 monomorphic = !map->is_dictionary_map(); | 7300 monomorphic = !map->is_dictionary_map(); |
| 7403 } | 7301 } |
| 7404 if (monomorphic) { | 7302 if (monomorphic) { |
| 7405 Handle<JSFunction> getter; | 7303 Handle<JSFunction> getter; |
| 7406 Handle<JSObject> holder; | 7304 Handle<JSObject> holder; |
| 7407 if (LookupGetter(map, name, &getter, &holder)) { | 7305 if (LookupGetter(map, name, &getter, &holder)) { |
| 7408 AddCheckConstantFunction(holder, Top(), map); | 7306 AddCheckConstantFunction(holder, Top(), map); |
| 7409 if (FLAG_inline_accessors && TryInlineGetter(getter, expr)) return; | 7307 if (FLAG_inline_accessors && TryInlineGetter(getter, expr)) return; |
| 7410 AddInstruction(new(zone()) HPushArgument(Pop())); | 7308 Add<HPushArgument>(Pop()); |
| 7411 instr = new(zone()) HCallConstantFunction(getter, 1); | 7309 instr = new(zone()) HCallConstantFunction(getter, 1); |
| 7412 } else { | 7310 } else { |
| 7413 instr = BuildLoadNamedMonomorphic(Pop(), name, expr, map); | 7311 instr = BuildLoadNamedMonomorphic(Pop(), name, expr, map); |
| 7414 } | 7312 } |
| 7415 } else if (types != NULL && types->length() > 1) { | 7313 } else if (types != NULL && types->length() > 1) { |
| 7416 return HandlePolymorphicLoadNamedField(expr, Pop(), types, name); | 7314 return HandlePolymorphicLoadNamedField(expr, Pop(), types, name); |
| 7417 } else { | 7315 } else { |
| 7418 instr = BuildLoadNamedGeneric(Pop(), name, expr); | 7316 instr = BuildLoadNamedGeneric(Pop(), name, expr); |
| 7419 } | 7317 } |
| 7420 | 7318 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 7442 } | 7340 } |
| 7443 instr->set_position(expr->position()); | 7341 instr->set_position(expr->position()); |
| 7444 return ast_context()->ReturnInstruction(instr, expr->id()); | 7342 return ast_context()->ReturnInstruction(instr, expr->id()); |
| 7445 } | 7343 } |
| 7446 | 7344 |
| 7447 | 7345 |
| 7448 void HOptimizedGraphBuilder::AddCheckPrototypeMaps(Handle<JSObject> holder, | 7346 void HOptimizedGraphBuilder::AddCheckPrototypeMaps(Handle<JSObject> holder, |
| 7449 Handle<Map> receiver_map) { | 7347 Handle<Map> receiver_map) { |
| 7450 if (!holder.is_null()) { | 7348 if (!holder.is_null()) { |
| 7451 Handle<JSObject> prototype(JSObject::cast(receiver_map->prototype())); | 7349 Handle<JSObject> prototype(JSObject::cast(receiver_map->prototype())); |
| 7452 AddInstruction(new(zone()) HCheckPrototypeMaps( | 7350 Add<HCheckPrototypeMaps>(prototype, holder, zone(), top_info()); |
| 7453 prototype, holder, zone(), top_info())); | |
| 7454 } | 7351 } |
| 7455 } | 7352 } |
| 7456 | 7353 |
| 7457 | 7354 |
| 7458 void HOptimizedGraphBuilder::AddCheckConstantFunction( | 7355 void HOptimizedGraphBuilder::AddCheckConstantFunction( |
| 7459 Handle<JSObject> holder, | 7356 Handle<JSObject> holder, |
| 7460 HValue* receiver, | 7357 HValue* receiver, |
| 7461 Handle<Map> receiver_map) { | 7358 Handle<Map> receiver_map) { |
| 7462 // Constant functions have the nice property that the map will change if they | 7359 // Constant functions have the nice property that the map will change if they |
| 7463 // are overwritten. Therefore it is enough to check the map of the holder and | 7360 // are overwritten. Therefore it is enough to check the map of the holder and |
| (...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7870 function, | 7767 function, |
| 7871 undefined, | 7768 undefined, |
| 7872 function_state()->inlining_kind(), | 7769 function_state()->inlining_kind(), |
| 7873 undefined_receiver); | 7770 undefined_receiver); |
| 7874 #ifdef V8_TARGET_ARCH_IA32 | 7771 #ifdef V8_TARGET_ARCH_IA32 |
| 7875 // IA32 only, overwrite the caller's context in the deoptimization | 7772 // IA32 only, overwrite the caller's context in the deoptimization |
| 7876 // environment with the correct one. | 7773 // environment with the correct one. |
| 7877 // | 7774 // |
| 7878 // TODO(kmillikin): implement the same inlining on other platforms so we | 7775 // TODO(kmillikin): implement the same inlining on other platforms so we |
| 7879 // can remove the unsightly ifdefs in this function. | 7776 // can remove the unsightly ifdefs in this function. |
| 7880 HConstant* context = | 7777 HConstant* context = Add<HConstant>(Handle<Context>(target->context())); |
| 7881 new(zone()) HConstant(Handle<Context>(target->context())); | |
| 7882 AddInstruction(context); | |
| 7883 inner_env->BindContext(context); | 7778 inner_env->BindContext(context); |
| 7884 #endif | 7779 #endif |
| 7885 | 7780 |
| 7886 AddSimulate(return_id); | 7781 AddSimulate(return_id); |
| 7887 current_block()->UpdateEnvironment(inner_env); | 7782 current_block()->UpdateEnvironment(inner_env); |
| 7888 HArgumentsObject* arguments_object = NULL; | 7783 HArgumentsObject* arguments_object = NULL; |
| 7889 | 7784 |
| 7890 // If the function uses arguments object create and bind one, also copy | 7785 // If the function uses arguments object create and bind one, also copy |
| 7891 // current arguments values to use them for materialization. | 7786 // current arguments values to use them for materialization. |
| 7892 if (function->scope()->arguments() != NULL) { | 7787 if (function->scope()->arguments() != NULL) { |
| 7893 ASSERT(function->scope()->arguments()->IsStackAllocated()); | 7788 ASSERT(function->scope()->arguments()->IsStackAllocated()); |
| 7894 HEnvironment* arguments_env = inner_env->arguments_environment(); | 7789 HEnvironment* arguments_env = inner_env->arguments_environment(); |
| 7895 int arguments_count = arguments_env->parameter_count(); | 7790 int arguments_count = arguments_env->parameter_count(); |
| 7896 arguments_object = new(zone()) HArgumentsObject(arguments_count, zone()); | 7791 arguments_object = Add<HArgumentsObject>(arguments_count, zone()); |
| 7897 inner_env->Bind(function->scope()->arguments(), arguments_object); | 7792 inner_env->Bind(function->scope()->arguments(), arguments_object); |
| 7898 for (int i = 0; i < arguments_count; i++) { | 7793 for (int i = 0; i < arguments_count; i++) { |
| 7899 arguments_object->AddArgument(arguments_env->Lookup(i), zone()); | 7794 arguments_object->AddArgument(arguments_env->Lookup(i), zone()); |
| 7900 } | 7795 } |
| 7901 AddInstruction(arguments_object); | |
| 7902 } | 7796 } |
| 7903 | 7797 |
| 7904 HEnterInlined* enter_inlined = | 7798 HEnterInlined* enter_inlined = |
| 7905 new(zone()) HEnterInlined(target, | 7799 Add<HEnterInlined>(target, arguments_count, function, |
| 7906 arguments_count, | 7800 function_state()->inlining_kind(), |
| 7907 function, | 7801 function->scope()->arguments(), |
| 7908 function_state()->inlining_kind(), | 7802 arguments_object, undefined_receiver, zone()); |
| 7909 function->scope()->arguments(), | |
| 7910 arguments_object, | |
| 7911 undefined_receiver, | |
| 7912 zone()); | |
| 7913 function_state()->set_entry(enter_inlined); | 7803 function_state()->set_entry(enter_inlined); |
| 7914 AddInstruction(enter_inlined); | |
| 7915 | 7804 |
| 7916 VisitDeclarations(target_info.scope()->declarations()); | 7805 VisitDeclarations(target_info.scope()->declarations()); |
| 7917 VisitStatements(function->body()); | 7806 VisitStatements(function->body()); |
| 7918 if (HasStackOverflow()) { | 7807 if (HasStackOverflow()) { |
| 7919 // Bail out if the inline function did, as we cannot residualize a call | 7808 // Bail out if the inline function did, as we cannot residualize a call |
| 7920 // instead. | 7809 // instead. |
| 7921 TraceInline(target, caller, "inline graph construction failed"); | 7810 TraceInline(target, caller, "inline graph construction failed"); |
| 7922 target_shared->DisableOptimization("inlining bailed out"); | 7811 target_shared->DisableOptimization("inlining bailed out"); |
| 7923 inline_bailout_ = true; | 7812 inline_bailout_ = true; |
| 7924 delete target_state; | 7813 delete target_state; |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8142 BuiltinFunctionId id = expr->target()->shared()->builtin_function_id(); | 8031 BuiltinFunctionId id = expr->target()->shared()->builtin_function_id(); |
| 8143 int argument_count = expr->arguments()->length() + 1; // Plus receiver. | 8032 int argument_count = expr->arguments()->length() + 1; // Plus receiver. |
| 8144 switch (id) { | 8033 switch (id) { |
| 8145 case kStringCharCodeAt: | 8034 case kStringCharCodeAt: |
| 8146 case kStringCharAt: | 8035 case kStringCharAt: |
| 8147 if (argument_count == 2 && check_type == STRING_CHECK) { | 8036 if (argument_count == 2 && check_type == STRING_CHECK) { |
| 8148 HValue* index = Pop(); | 8037 HValue* index = Pop(); |
| 8149 HValue* string = Pop(); | 8038 HValue* string = Pop(); |
| 8150 HValue* context = environment()->LookupContext(); | 8039 HValue* context = environment()->LookupContext(); |
| 8151 ASSERT(!expr->holder().is_null()); | 8040 ASSERT(!expr->holder().is_null()); |
| 8152 AddInstruction(new(zone()) HCheckPrototypeMaps( | 8041 Add<HCheckPrototypeMaps>(Call::GetPrototypeForPrimitiveCheck( |
| 8153 Call::GetPrototypeForPrimitiveCheck(STRING_CHECK, | 8042 STRING_CHECK, expr->holder()->GetIsolate()), |
| 8154 expr->holder()->GetIsolate()), | 8043 expr->holder(), zone(), top_info()); |
| 8155 expr->holder(), | |
| 8156 zone(), | |
| 8157 top_info())); | |
| 8158 HInstruction* char_code = | 8044 HInstruction* char_code = |
| 8159 BuildStringCharCodeAt(context, string, index); | 8045 BuildStringCharCodeAt(context, string, index); |
| 8160 if (id == kStringCharCodeAt) { | 8046 if (id == kStringCharCodeAt) { |
| 8161 ast_context()->ReturnInstruction(char_code, expr->id()); | 8047 ast_context()->ReturnInstruction(char_code, expr->id()); |
| 8162 return true; | 8048 return true; |
| 8163 } | 8049 } |
| 8164 AddInstruction(char_code); | 8050 AddInstruction(char_code); |
| 8165 HInstruction* result = | 8051 HInstruction* result = |
| 8166 HStringCharFromCode::New(zone(), context, char_code); | 8052 HStringCharFromCode::New(zone(), context, char_code); |
| 8167 ast_context()->ReturnInstruction(result, expr->id()); | 8053 ast_context()->ReturnInstruction(result, expr->id()); |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8238 } | 8124 } |
| 8239 ast_context()->ReturnInstruction(result, expr->id()); | 8125 ast_context()->ReturnInstruction(result, expr->id()); |
| 8240 return true; | 8126 return true; |
| 8241 } | 8127 } |
| 8242 break; | 8128 break; |
| 8243 case kMathRandom: | 8129 case kMathRandom: |
| 8244 if (argument_count == 1 && check_type == RECEIVER_MAP_CHECK) { | 8130 if (argument_count == 1 && check_type == RECEIVER_MAP_CHECK) { |
| 8245 AddCheckConstantFunction(expr->holder(), receiver, receiver_map); | 8131 AddCheckConstantFunction(expr->holder(), receiver, receiver_map); |
| 8246 Drop(1); // Receiver. | 8132 Drop(1); // Receiver. |
| 8247 HValue* context = environment()->LookupContext(); | 8133 HValue* context = environment()->LookupContext(); |
| 8248 HGlobalObject* global_object = new(zone()) HGlobalObject(context); | 8134 HGlobalObject* global_object = Add<HGlobalObject>(context); |
| 8249 AddInstruction(global_object); | |
| 8250 HRandom* result = new(zone()) HRandom(global_object); | 8135 HRandom* result = new(zone()) HRandom(global_object); |
| 8251 ast_context()->ReturnInstruction(result, expr->id()); | 8136 ast_context()->ReturnInstruction(result, expr->id()); |
| 8252 return true; | 8137 return true; |
| 8253 } | 8138 } |
| 8254 break; | 8139 break; |
| 8255 case kMathMax: | 8140 case kMathMax: |
| 8256 case kMathMin: | 8141 case kMathMin: |
| 8257 if (argument_count == 3 && check_type == RECEIVER_MAP_CHECK) { | 8142 if (argument_count == 3 && check_type == RECEIVER_MAP_CHECK) { |
| 8258 AddCheckConstantFunction(expr->holder(), receiver, receiver_map); | 8143 AddCheckConstantFunction(expr->holder(), receiver, receiver_map); |
| 8259 HValue* right = Pop(); | 8144 HValue* right = Pop(); |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8318 if (HasStackOverflow() || current_block() == NULL) return true; | 8203 if (HasStackOverflow() || current_block() == NULL) return true; |
| 8319 HValue* function = Top(); | 8204 HValue* function = Top(); |
| 8320 AddCheckConstantFunction(expr->holder(), function, function_map); | 8205 AddCheckConstantFunction(expr->holder(), function, function_map); |
| 8321 Drop(1); | 8206 Drop(1); |
| 8322 | 8207 |
| 8323 VisitForValue(args->at(0)); | 8208 VisitForValue(args->at(0)); |
| 8324 if (HasStackOverflow() || current_block() == NULL) return true; | 8209 if (HasStackOverflow() || current_block() == NULL) return true; |
| 8325 HValue* receiver = Pop(); | 8210 HValue* receiver = Pop(); |
| 8326 | 8211 |
| 8327 if (function_state()->outer() == NULL) { | 8212 if (function_state()->outer() == NULL) { |
| 8328 HInstruction* elements = AddInstruction( | 8213 HInstruction* elements = Add<HArgumentsElements>(false); |
| 8329 new(zone()) HArgumentsElements(false)); | 8214 HInstruction* length = Add<HArgumentsLength>(elements); |
| 8330 HInstruction* length = | 8215 HValue* wrapped_receiver = Add<HWrapReceiver>(receiver, function); |
| 8331 AddInstruction(new(zone()) HArgumentsLength(elements)); | |
| 8332 HValue* wrapped_receiver = | |
| 8333 AddInstruction(new(zone()) HWrapReceiver(receiver, function)); | |
| 8334 HInstruction* result = | 8216 HInstruction* result = |
| 8335 new(zone()) HApplyArguments(function, | 8217 new(zone()) HApplyArguments(function, |
| 8336 wrapped_receiver, | 8218 wrapped_receiver, |
| 8337 length, | 8219 length, |
| 8338 elements); | 8220 elements); |
| 8339 result->set_position(expr->position()); | 8221 result->set_position(expr->position()); |
| 8340 ast_context()->ReturnInstruction(result, expr->id()); | 8222 ast_context()->ReturnInstruction(result, expr->id()); |
| 8341 return true; | 8223 return true; |
| 8342 } else { | 8224 } else { |
| 8343 // We are inside inlined function and we know exactly what is inside | 8225 // We are inside inlined function and we know exactly what is inside |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8548 if (known_global_function) { | 8430 if (known_global_function) { |
| 8549 // Push the global object instead of the global receiver because | 8431 // Push the global object instead of the global receiver because |
| 8550 // code generated by the full code generator expects it. | 8432 // code generated by the full code generator expects it. |
| 8551 HValue* context = environment()->LookupContext(); | 8433 HValue* context = environment()->LookupContext(); |
| 8552 HGlobalObject* global_object = new(zone()) HGlobalObject(context); | 8434 HGlobalObject* global_object = new(zone()) HGlobalObject(context); |
| 8553 PushAndAdd(global_object); | 8435 PushAndAdd(global_object); |
| 8554 CHECK_ALIVE(VisitExpressions(expr->arguments())); | 8436 CHECK_ALIVE(VisitExpressions(expr->arguments())); |
| 8555 | 8437 |
| 8556 CHECK_ALIVE(VisitForValue(expr->expression())); | 8438 CHECK_ALIVE(VisitForValue(expr->expression())); |
| 8557 HValue* function = Pop(); | 8439 HValue* function = Pop(); |
| 8558 AddInstruction(new(zone()) HCheckFunction(function, expr->target())); | 8440 Add<HCheckFunction>(function, expr->target()); |
| 8559 | 8441 |
| 8560 // Replace the global object with the global receiver. | 8442 // Replace the global object with the global receiver. |
| 8561 HGlobalReceiver* global_receiver = | 8443 HGlobalReceiver* global_receiver = Add<HGlobalReceiver>(global_object); |
| 8562 new(zone()) HGlobalReceiver(global_object); | |
| 8563 // Index of the receiver from the top of the expression stack. | 8444 // Index of the receiver from the top of the expression stack. |
| 8564 const int receiver_index = argument_count - 1; | 8445 const int receiver_index = argument_count - 1; |
| 8565 AddInstruction(global_receiver); | |
| 8566 ASSERT(environment()->ExpressionStackAt(receiver_index)-> | 8446 ASSERT(environment()->ExpressionStackAt(receiver_index)-> |
| 8567 IsGlobalObject()); | 8447 IsGlobalObject()); |
| 8568 environment()->SetExpressionStackAt(receiver_index, global_receiver); | 8448 environment()->SetExpressionStackAt(receiver_index, global_receiver); |
| 8569 | 8449 |
| 8570 if (TryInlineBuiltinFunctionCall(expr, false)) { // Nothing to drop. | 8450 if (TryInlineBuiltinFunctionCall(expr, false)) { // Nothing to drop. |
| 8571 if (FLAG_trace_inlining) { | 8451 if (FLAG_trace_inlining) { |
| 8572 PrintF("Inlining builtin "); | 8452 PrintF("Inlining builtin "); |
| 8573 expr->target()->ShortPrint(); | 8453 expr->target()->ShortPrint(); |
| 8574 PrintF("\n"); | 8454 PrintF("\n"); |
| 8575 } | 8455 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 8586 // because it is likely to generate better code. | 8466 // because it is likely to generate better code. |
| 8587 HValue* context = environment()->LookupContext(); | 8467 HValue* context = environment()->LookupContext(); |
| 8588 call = PreProcessCall( | 8468 call = PreProcessCall( |
| 8589 new(zone()) HCallNamed(context, var->name(), argument_count)); | 8469 new(zone()) HCallNamed(context, var->name(), argument_count)); |
| 8590 } else { | 8470 } else { |
| 8591 call = PreProcessCall(new(zone()) HCallKnownGlobal(expr->target(), | 8471 call = PreProcessCall(new(zone()) HCallKnownGlobal(expr->target(), |
| 8592 argument_count)); | 8472 argument_count)); |
| 8593 } | 8473 } |
| 8594 } else { | 8474 } else { |
| 8595 HValue* context = environment()->LookupContext(); | 8475 HValue* context = environment()->LookupContext(); |
| 8596 HGlobalObject* receiver = new(zone()) HGlobalObject(context); | 8476 HGlobalObject* receiver = Add<HGlobalObject>(context); |
| 8597 AddInstruction(receiver); | |
| 8598 PushAndAdd(new(zone()) HPushArgument(receiver)); | 8477 PushAndAdd(new(zone()) HPushArgument(receiver)); |
| 8599 CHECK_ALIVE(VisitArgumentList(expr->arguments())); | 8478 CHECK_ALIVE(VisitArgumentList(expr->arguments())); |
| 8600 | 8479 |
| 8601 call = new(zone()) HCallGlobal(context, var->name(), argument_count); | 8480 call = new(zone()) HCallGlobal(context, var->name(), argument_count); |
| 8602 Drop(argument_count); | 8481 Drop(argument_count); |
| 8603 } | 8482 } |
| 8604 | 8483 |
| 8605 } else if (expr->IsMonomorphic()) { | 8484 } else if (expr->IsMonomorphic()) { |
| 8606 // The function is on the stack in the unoptimized code during | 8485 // The function is on the stack in the unoptimized code during |
| 8607 // evaluation of the arguments. | 8486 // evaluation of the arguments. |
| 8608 CHECK_ALIVE(VisitForValue(expr->expression())); | 8487 CHECK_ALIVE(VisitForValue(expr->expression())); |
| 8609 HValue* function = Top(); | 8488 HValue* function = Top(); |
| 8610 HValue* context = environment()->LookupContext(); | 8489 HValue* context = environment()->LookupContext(); |
| 8611 HGlobalObject* global = new(zone()) HGlobalObject(context); | 8490 HGlobalObject* global = Add<HGlobalObject>(context); |
| 8612 AddInstruction(global); | |
| 8613 HGlobalReceiver* receiver = new(zone()) HGlobalReceiver(global); | 8491 HGlobalReceiver* receiver = new(zone()) HGlobalReceiver(global); |
| 8614 PushAndAdd(receiver); | 8492 PushAndAdd(receiver); |
| 8615 CHECK_ALIVE(VisitExpressions(expr->arguments())); | 8493 CHECK_ALIVE(VisitExpressions(expr->arguments())); |
| 8616 AddInstruction(new(zone()) HCheckFunction(function, expr->target())); | 8494 Add<HCheckFunction>(function, expr->target()); |
| 8617 | 8495 |
| 8618 if (TryInlineBuiltinFunctionCall(expr, true)) { // Drop the function. | 8496 if (TryInlineBuiltinFunctionCall(expr, true)) { // Drop the function. |
| 8619 if (FLAG_trace_inlining) { | 8497 if (FLAG_trace_inlining) { |
| 8620 PrintF("Inlining builtin "); | 8498 PrintF("Inlining builtin "); |
| 8621 expr->target()->ShortPrint(); | 8499 expr->target()->ShortPrint(); |
| 8622 PrintF("\n"); | 8500 PrintF("\n"); |
| 8623 } | 8501 } |
| 8624 return; | 8502 return; |
| 8625 } | 8503 } |
| 8626 | 8504 |
| 8627 if (TryInlineCall(expr, true)) { // Drop function from environment. | 8505 if (TryInlineCall(expr, true)) { // Drop function from environment. |
| 8628 return; | 8506 return; |
| 8629 } else { | 8507 } else { |
| 8630 call = PreProcessCall( | 8508 call = PreProcessCall( |
| 8631 new(zone()) HInvokeFunction(context, | 8509 new(zone()) HInvokeFunction(context, |
| 8632 function, | 8510 function, |
| 8633 expr->target(), | 8511 expr->target(), |
| 8634 argument_count)); | 8512 argument_count)); |
| 8635 Drop(1); // The function. | 8513 Drop(1); // The function. |
| 8636 } | 8514 } |
| 8637 | 8515 |
| 8638 } else { | 8516 } else { |
| 8639 CHECK_ALIVE(VisitForValue(expr->expression())); | 8517 CHECK_ALIVE(VisitForValue(expr->expression())); |
| 8640 HValue* function = Top(); | 8518 HValue* function = Top(); |
| 8641 HValue* context = environment()->LookupContext(); | 8519 HValue* context = environment()->LookupContext(); |
| 8642 HGlobalObject* global_object = new(zone()) HGlobalObject(context); | 8520 HGlobalObject* global_object = Add<HGlobalObject>(context); |
| 8643 AddInstruction(global_object); | 8521 HGlobalReceiver* receiver = Add<HGlobalReceiver>(global_object); |
| 8644 HGlobalReceiver* receiver = new(zone()) HGlobalReceiver(global_object); | |
| 8645 AddInstruction(receiver); | |
| 8646 PushAndAdd(new(zone()) HPushArgument(receiver)); | 8522 PushAndAdd(new(zone()) HPushArgument(receiver)); |
| 8647 CHECK_ALIVE(VisitArgumentList(expr->arguments())); | 8523 CHECK_ALIVE(VisitArgumentList(expr->arguments())); |
| 8648 | 8524 |
| 8649 call = new(zone()) HCallFunction(context, function, argument_count); | 8525 call = new(zone()) HCallFunction(context, function, argument_count); |
| 8650 Drop(argument_count + 1); | 8526 Drop(argument_count + 1); |
| 8651 } | 8527 } |
| 8652 } | 8528 } |
| 8653 | 8529 |
| 8654 call->set_position(expr->position()); | 8530 call->set_position(expr->position()); |
| 8655 return ast_context()->ReturnInstruction(call, expr->id()); | 8531 return ast_context()->ReturnInstruction(call, expr->id()); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 8673 | 8549 |
| 8674 if (FLAG_inline_construct && | 8550 if (FLAG_inline_construct && |
| 8675 expr->IsMonomorphic() && | 8551 expr->IsMonomorphic() && |
| 8676 IsAllocationInlineable(expr->target())) { | 8552 IsAllocationInlineable(expr->target())) { |
| 8677 // The constructor function is on the stack in the unoptimized code | 8553 // The constructor function is on the stack in the unoptimized code |
| 8678 // during evaluation of the arguments. | 8554 // during evaluation of the arguments. |
| 8679 CHECK_ALIVE(VisitForValue(expr->expression())); | 8555 CHECK_ALIVE(VisitForValue(expr->expression())); |
| 8680 HValue* function = Top(); | 8556 HValue* function = Top(); |
| 8681 CHECK_ALIVE(VisitExpressions(expr->arguments())); | 8557 CHECK_ALIVE(VisitExpressions(expr->arguments())); |
| 8682 Handle<JSFunction> constructor = expr->target(); | 8558 Handle<JSFunction> constructor = expr->target(); |
| 8683 HValue* check = AddInstruction( | 8559 HValue* check = Add<HCheckFunction>(function, constructor); |
| 8684 new(zone()) HCheckFunction(function, constructor)); | |
| 8685 | 8560 |
| 8686 // Force completion of inobject slack tracking before generating | 8561 // Force completion of inobject slack tracking before generating |
| 8687 // allocation code to finalize instance size. | 8562 // allocation code to finalize instance size. |
| 8688 if (constructor->shared()->IsInobjectSlackTrackingInProgress()) { | 8563 if (constructor->shared()->IsInobjectSlackTrackingInProgress()) { |
| 8689 constructor->shared()->CompleteInobjectSlackTracking(); | 8564 constructor->shared()->CompleteInobjectSlackTracking(); |
| 8690 } | 8565 } |
| 8691 | 8566 |
| 8692 // Replace the constructor function with a newly allocated receiver. | 8567 // Replace the constructor function with a newly allocated receiver. |
| 8693 HInstruction* receiver = new(zone()) HAllocateObject(context, constructor); | 8568 HInstruction* receiver = Add<HAllocateObject>(context, constructor); |
| 8694 // Index of the receiver from the top of the expression stack. | 8569 // Index of the receiver from the top of the expression stack. |
| 8695 const int receiver_index = argument_count - 1; | 8570 const int receiver_index = argument_count - 1; |
| 8696 AddInstruction(receiver); | |
| 8697 ASSERT(environment()->ExpressionStackAt(receiver_index) == function); | 8571 ASSERT(environment()->ExpressionStackAt(receiver_index) == function); |
| 8698 environment()->SetExpressionStackAt(receiver_index, receiver); | 8572 environment()->SetExpressionStackAt(receiver_index, receiver); |
| 8699 | 8573 |
| 8700 if (TryInlineConstruct(expr, receiver)) return; | 8574 if (TryInlineConstruct(expr, receiver)) return; |
| 8701 | 8575 |
| 8702 // TODO(mstarzinger): For now we remove the previous HAllocateObject and | 8576 // TODO(mstarzinger): For now we remove the previous HAllocateObject and |
| 8703 // add HPushArgument for the arguments in case inlining failed. What we | 8577 // add HPushArgument for the arguments in case inlining failed. What we |
| 8704 // actually should do is emit HInvokeFunction on the constructor instead | 8578 // actually should do is emit HInvokeFunction on the constructor instead |
| 8705 // of using HCallNew as a fallback. | 8579 // of using HCallNew as a fallback. |
| 8706 receiver->DeleteAndReplaceWith(NULL); | 8580 receiver->DeleteAndReplaceWith(NULL); |
| 8707 check->DeleteAndReplaceWith(NULL); | 8581 check->DeleteAndReplaceWith(NULL); |
| 8708 environment()->SetExpressionStackAt(receiver_index, function); | 8582 environment()->SetExpressionStackAt(receiver_index, function); |
| 8709 HInstruction* call = PreProcessCall( | 8583 HInstruction* call = PreProcessCall( |
| 8710 new(zone()) HCallNew(context, function, argument_count)); | 8584 new(zone()) HCallNew(context, function, argument_count)); |
| 8711 call->set_position(expr->position()); | 8585 call->set_position(expr->position()); |
| 8712 return ast_context()->ReturnInstruction(call, expr->id()); | 8586 return ast_context()->ReturnInstruction(call, expr->id()); |
| 8713 } else { | 8587 } else { |
| 8714 // The constructor function is both an operand to the instruction and an | 8588 // The constructor function is both an operand to the instruction and an |
| 8715 // argument to the construct call. | 8589 // argument to the construct call. |
| 8716 Handle<JSFunction> array_function( | 8590 Handle<JSFunction> array_function( |
| 8717 isolate()->global_context()->array_function(), isolate()); | 8591 isolate()->global_context()->array_function(), isolate()); |
| 8718 CHECK_ALIVE(VisitArgument(expr->expression())); | 8592 CHECK_ALIVE(VisitArgument(expr->expression())); |
| 8719 HValue* constructor = HPushArgument::cast(Top())->argument(); | 8593 HValue* constructor = HPushArgument::cast(Top())->argument(); |
| 8720 CHECK_ALIVE(VisitArgumentList(expr->arguments())); | 8594 CHECK_ALIVE(VisitArgumentList(expr->arguments())); |
| 8721 HCallNew* call; | 8595 HCallNew* call; |
| 8722 if (expr->target().is_identical_to(array_function)) { | 8596 if (expr->target().is_identical_to(array_function)) { |
| 8723 Handle<Cell> cell = expr->allocation_info_cell(); | 8597 Handle<Cell> cell = expr->allocation_info_cell(); |
| 8724 AddInstruction(new(zone()) HCheckFunction(constructor, array_function)); | 8598 Add<HCheckFunction>(constructor, array_function); |
| 8725 call = new(zone()) HCallNewArray(context, constructor, argument_count, | 8599 call = new(zone()) HCallNewArray(context, constructor, argument_count, |
| 8726 cell, expr->elements_kind()); | 8600 cell, expr->elements_kind()); |
| 8727 } else { | 8601 } else { |
| 8728 call = new(zone()) HCallNew(context, constructor, argument_count); | 8602 call = new(zone()) HCallNew(context, constructor, argument_count); |
| 8729 } | 8603 } |
| 8730 Drop(argument_count); | 8604 Drop(argument_count); |
| 8731 call->set_position(expr->position()); | 8605 call->set_position(expr->position()); |
| 8732 return ast_context()->ReturnInstruction(call, expr->id()); | 8606 return ast_context()->ReturnInstruction(call, expr->id()); |
| 8733 } | 8607 } |
| 8734 } | 8608 } |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8937 Representation rep = ToRepresentation(info); | 8811 Representation rep = ToRepresentation(info); |
| 8938 if (rep.IsNone() || rep.IsTagged()) { | 8812 if (rep.IsNone() || rep.IsTagged()) { |
| 8939 rep = Representation::Smi(); | 8813 rep = Representation::Smi(); |
| 8940 } | 8814 } |
| 8941 | 8815 |
| 8942 if (returns_original_input) { | 8816 if (returns_original_input) { |
| 8943 // We need an explicit HValue representing ToNumber(input). The | 8817 // We need an explicit HValue representing ToNumber(input). The |
| 8944 // actual HChange instruction we need is (sometimes) added in a later | 8818 // actual HChange instruction we need is (sometimes) added in a later |
| 8945 // phase, so it is not available now to be used as an input to HAdd and | 8819 // phase, so it is not available now to be used as an input to HAdd and |
| 8946 // as the return value. | 8820 // as the return value. |
| 8947 HInstruction* number_input = new(zone()) HForceRepresentation(Pop(), rep); | 8821 HInstruction* number_input = Add<HForceRepresentation>(Pop(), rep); |
| 8948 if (!rep.IsDouble()) { | 8822 if (!rep.IsDouble()) { |
| 8949 number_input->SetFlag(HInstruction::kFlexibleRepresentation); | 8823 number_input->SetFlag(HInstruction::kFlexibleRepresentation); |
| 8950 number_input->SetFlag(HInstruction::kCannotBeTagged); | 8824 number_input->SetFlag(HInstruction::kCannotBeTagged); |
| 8951 } | 8825 } |
| 8952 AddInstruction(number_input); | |
| 8953 Push(number_input); | 8826 Push(number_input); |
| 8954 } | 8827 } |
| 8955 | 8828 |
| 8956 // The addition has no side effects, so we do not need | 8829 // The addition has no side effects, so we do not need |
| 8957 // to simulate the expression stack after this instruction. | 8830 // to simulate the expression stack after this instruction. |
| 8958 // Any later failures deopt to the load of the input or earlier. | 8831 // Any later failures deopt to the load of the input or earlier. |
| 8959 HConstant* delta = (expr->op() == Token::INC) | 8832 HConstant* delta = (expr->op() == Token::INC) |
| 8960 ? graph()->GetConstant1() | 8833 ? graph()->GetConstant1() |
| 8961 : graph()->GetConstantMinus1(); | 8834 : graph()->GetConstantMinus1(); |
| 8962 HValue* context = environment()->LookupContext(); | 8835 HValue* context = environment()->LookupContext(); |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9025 for (int i = 0; i < count; ++i) { | 8898 for (int i = 0; i < count; ++i) { |
| 9026 if (var == current_info()->scope()->parameter(i)) { | 8899 if (var == current_info()->scope()->parameter(i)) { |
| 9027 return Bailout("assignment to parameter in arguments object"); | 8900 return Bailout("assignment to parameter in arguments object"); |
| 9028 } | 8901 } |
| 9029 } | 8902 } |
| 9030 } | 8903 } |
| 9031 | 8904 |
| 9032 HValue* context = BuildContextChainWalk(var); | 8905 HValue* context = BuildContextChainWalk(var); |
| 9033 HStoreContextSlot::Mode mode = IsLexicalVariableMode(var->mode()) | 8906 HStoreContextSlot::Mode mode = IsLexicalVariableMode(var->mode()) |
| 9034 ? HStoreContextSlot::kCheckDeoptimize : HStoreContextSlot::kNoCheck; | 8907 ? HStoreContextSlot::kCheckDeoptimize : HStoreContextSlot::kNoCheck; |
| 9035 HStoreContextSlot* instr = | 8908 HStoreContextSlot* instr = Add<HStoreContextSlot>(context, var->index(), |
| 9036 new(zone()) HStoreContextSlot(context, var->index(), mode, after); | 8909 mode, after); |
| 9037 AddInstruction(instr); | |
| 9038 if (instr->HasObservableSideEffects()) { | 8910 if (instr->HasObservableSideEffects()) { |
| 9039 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE); | 8911 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE); |
| 9040 } | 8912 } |
| 9041 break; | 8913 break; |
| 9042 } | 8914 } |
| 9043 | 8915 |
| 9044 case Variable::LOOKUP: | 8916 case Variable::LOOKUP: |
| 9045 return Bailout("lookup variable in count operation"); | 8917 return Bailout("lookup variable in count operation"); |
| 9046 } | 8918 } |
| 9047 | 8919 |
| (...skipping 600 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9648 } | 9520 } |
| 9649 } | 9521 } |
| 9650 | 9522 |
| 9651 // If the target is not null we have found a known global function that is | 9523 // If the target is not null we have found a known global function that is |
| 9652 // assumed to stay the same for this instanceof. | 9524 // assumed to stay the same for this instanceof. |
| 9653 if (target.is_null()) { | 9525 if (target.is_null()) { |
| 9654 HInstanceOf* result = new(zone()) HInstanceOf(context, left, right); | 9526 HInstanceOf* result = new(zone()) HInstanceOf(context, left, right); |
| 9655 result->set_position(expr->position()); | 9527 result->set_position(expr->position()); |
| 9656 return ast_context()->ReturnInstruction(result, expr->id()); | 9528 return ast_context()->ReturnInstruction(result, expr->id()); |
| 9657 } else { | 9529 } else { |
| 9658 AddInstruction(new(zone()) HCheckFunction(right, target)); | 9530 Add<HCheckFunction>(right, target); |
| 9659 HInstanceOfKnownGlobal* result = | 9531 HInstanceOfKnownGlobal* result = |
| 9660 new(zone()) HInstanceOfKnownGlobal(context, left, target); | 9532 new(zone()) HInstanceOfKnownGlobal(context, left, target); |
| 9661 result->set_position(expr->position()); | 9533 result->set_position(expr->position()); |
| 9662 return ast_context()->ReturnInstruction(result, expr->id()); | 9534 return ast_context()->ReturnInstruction(result, expr->id()); |
| 9663 } | 9535 } |
| 9664 } else if (op == Token::IN) { | 9536 } else if (op == Token::IN) { |
| 9665 HIn* result = new(zone()) HIn(context, left, right); | 9537 HIn* result = new(zone()) HIn(context, left, right); |
| 9666 result->set_position(expr->position()); | 9538 result->set_position(expr->position()); |
| 9667 return ast_context()->ReturnInstruction(result, expr->id()); | 9539 return ast_context()->ReturnInstruction(result, expr->id()); |
| 9668 } else if (combined_type->Is(Type::Receiver())) { | 9540 } else if (combined_type->Is(Type::Receiver())) { |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9762 } | 9634 } |
| 9763 | 9635 |
| 9764 | 9636 |
| 9765 HInstruction* HOptimizedGraphBuilder::BuildFastLiteral( | 9637 HInstruction* HOptimizedGraphBuilder::BuildFastLiteral( |
| 9766 HValue* context, | 9638 HValue* context, |
| 9767 Handle<JSObject> boilerplate_object, | 9639 Handle<JSObject> boilerplate_object, |
| 9768 Handle<JSObject> original_boilerplate_object, | 9640 Handle<JSObject> original_boilerplate_object, |
| 9769 int data_size, | 9641 int data_size, |
| 9770 int pointer_size, | 9642 int pointer_size, |
| 9771 AllocationSiteMode mode) { | 9643 AllocationSiteMode mode) { |
| 9772 Zone* zone = this->zone(); | |
| 9773 NoObservableSideEffectsScope no_effects(this); | 9644 NoObservableSideEffectsScope no_effects(this); |
| 9774 | 9645 |
| 9775 HInstruction* target = NULL; | 9646 HInstruction* target = NULL; |
| 9776 HInstruction* data_target = NULL; | 9647 HInstruction* data_target = NULL; |
| 9777 | 9648 |
| 9778 HAllocate::Flags flags = HAllocate::DefaultFlags(); | 9649 HAllocate::Flags flags = HAllocate::DefaultFlags(); |
| 9779 | 9650 |
| 9780 if (isolate()->heap()->ShouldGloballyPretenure()) { | 9651 if (isolate()->heap()->ShouldGloballyPretenure()) { |
| 9781 if (data_size != 0) { | 9652 if (data_size != 0) { |
| 9782 HAllocate::Flags data_flags = | 9653 HAllocate::Flags data_flags = |
| 9783 static_cast<HAllocate::Flags>(HAllocate::DefaultFlags() | | 9654 static_cast<HAllocate::Flags>(HAllocate::DefaultFlags() | |
| 9784 HAllocate::CAN_ALLOCATE_IN_OLD_DATA_SPACE); | 9655 HAllocate::CAN_ALLOCATE_IN_OLD_DATA_SPACE); |
| 9785 HValue* size_in_bytes = AddInstruction(new(zone) HConstant(data_size)); | 9656 HValue* size_in_bytes = Add<HConstant>(data_size); |
| 9786 data_target = AddInstruction(new(zone) HAllocate( | 9657 data_target = Add<HAllocate>(context, size_in_bytes, |
| 9787 context, size_in_bytes, HType::JSObject(), data_flags)); | 9658 HType::JSObject(), data_flags); |
| 9788 Handle<Map> free_space_map = isolate()->factory()->free_space_map(); | 9659 Handle<Map> free_space_map = isolate()->factory()->free_space_map(); |
| 9789 AddStoreMapConstant(data_target, free_space_map); | 9660 AddStoreMapConstant(data_target, free_space_map); |
| 9790 HObjectAccess access = | 9661 HObjectAccess access = |
| 9791 HObjectAccess::ForJSObjectOffset(FreeSpace::kSizeOffset); | 9662 HObjectAccess::ForJSObjectOffset(FreeSpace::kSizeOffset); |
| 9792 AddStore(data_target, access, size_in_bytes); | 9663 AddStore(data_target, access, size_in_bytes); |
| 9793 } | 9664 } |
| 9794 if (pointer_size != 0) { | 9665 if (pointer_size != 0) { |
| 9795 flags = static_cast<HAllocate::Flags>( | 9666 flags = static_cast<HAllocate::Flags>( |
| 9796 flags | HAllocate::CAN_ALLOCATE_IN_OLD_POINTER_SPACE); | 9667 flags | HAllocate::CAN_ALLOCATE_IN_OLD_POINTER_SPACE); |
| 9797 HValue* size_in_bytes = AddInstruction(new(zone) HConstant(pointer_size)); | 9668 HValue* size_in_bytes = Add<HConstant>(pointer_size); |
| 9798 target = AddInstruction(new(zone) HAllocate(context, | 9669 target = Add<HAllocate>(context, size_in_bytes, HType::JSObject(), flags); |
| 9799 size_in_bytes, HType::JSObject(), flags)); | |
| 9800 } | 9670 } |
| 9801 } else { | 9671 } else { |
| 9802 HValue* size_in_bytes = | 9672 HValue* size_in_bytes = Add<HConstant>(data_size + pointer_size); |
| 9803 AddInstruction(new(zone) HConstant(data_size + pointer_size)); | 9673 target = Add<HAllocate>(context, size_in_bytes, HType::JSObject(), flags); |
| 9804 target = AddInstruction(new(zone) HAllocate(context, size_in_bytes, | |
| 9805 HType::JSObject(), flags)); | |
| 9806 } | 9674 } |
| 9807 | 9675 |
| 9808 int offset = 0; | 9676 int offset = 0; |
| 9809 int data_offset = 0; | 9677 int data_offset = 0; |
| 9810 BuildEmitDeepCopy(boilerplate_object, original_boilerplate_object, target, | 9678 BuildEmitDeepCopy(boilerplate_object, original_boilerplate_object, target, |
| 9811 &offset, data_target, &data_offset, mode); | 9679 &offset, data_target, &data_offset, mode); |
| 9812 return target; | 9680 return target; |
| 9813 } | 9681 } |
| 9814 | 9682 |
| 9815 | 9683 |
| 9816 void HOptimizedGraphBuilder::BuildEmitDeepCopy( | 9684 void HOptimizedGraphBuilder::BuildEmitDeepCopy( |
| 9817 Handle<JSObject> boilerplate_object, | 9685 Handle<JSObject> boilerplate_object, |
| 9818 Handle<JSObject> original_boilerplate_object, | 9686 Handle<JSObject> original_boilerplate_object, |
| 9819 HInstruction* target, | 9687 HInstruction* target, |
| 9820 int* offset, | 9688 int* offset, |
| 9821 HInstruction* data_target, | 9689 HInstruction* data_target, |
| 9822 int* data_offset, | 9690 int* data_offset, |
| 9823 AllocationSiteMode mode) { | 9691 AllocationSiteMode mode) { |
| 9824 Zone* zone = this->zone(); | |
| 9825 | |
| 9826 Handle<FixedArrayBase> elements(boilerplate_object->elements()); | 9692 Handle<FixedArrayBase> elements(boilerplate_object->elements()); |
| 9827 Handle<FixedArrayBase> original_elements( | 9693 Handle<FixedArrayBase> original_elements( |
| 9828 original_boilerplate_object->elements()); | 9694 original_boilerplate_object->elements()); |
| 9829 ElementsKind kind = boilerplate_object->map()->elements_kind(); | 9695 ElementsKind kind = boilerplate_object->map()->elements_kind(); |
| 9830 | 9696 |
| 9831 int object_offset = *offset; | 9697 int object_offset = *offset; |
| 9832 int object_size = boilerplate_object->map()->instance_size(); | 9698 int object_size = boilerplate_object->map()->instance_size(); |
| 9833 int elements_size = (elements->length() > 0 && | 9699 int elements_size = (elements->length() > 0 && |
| 9834 elements->map() != isolate()->heap()->fixed_cow_array_map()) ? | 9700 elements->map() != isolate()->heap()->fixed_cow_array_map()) ? |
| 9835 elements->Size() : 0; | 9701 elements->Size() : 0; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 9851 HValue* object_elements = BuildEmitObjectHeader(boilerplate_object, target, | 9717 HValue* object_elements = BuildEmitObjectHeader(boilerplate_object, target, |
| 9852 data_target, object_offset, elements_offset, elements_size); | 9718 data_target, object_offset, elements_offset, elements_size); |
| 9853 if (object_elements != NULL) { | 9719 if (object_elements != NULL) { |
| 9854 BuildEmitElements(elements, original_elements, kind, object_elements, | 9720 BuildEmitElements(elements, original_elements, kind, object_elements, |
| 9855 target, offset, data_target, data_offset); | 9721 target, offset, data_target, data_offset); |
| 9856 } | 9722 } |
| 9857 | 9723 |
| 9858 // Copy in-object properties. | 9724 // Copy in-object properties. |
| 9859 if (boilerplate_object->map()->NumberOfFields() != 0) { | 9725 if (boilerplate_object->map()->NumberOfFields() != 0) { |
| 9860 HValue* object_properties = | 9726 HValue* object_properties = |
| 9861 AddInstruction(new(zone) HInnerAllocatedObject(target, object_offset)); | 9727 Add<HInnerAllocatedObject>(target, object_offset); |
| 9862 BuildEmitInObjectProperties(boilerplate_object, original_boilerplate_object, | 9728 BuildEmitInObjectProperties(boilerplate_object, original_boilerplate_object, |
| 9863 object_properties, target, offset, data_target, data_offset); | 9729 object_properties, target, offset, data_target, data_offset); |
| 9864 } | 9730 } |
| 9865 | 9731 |
| 9866 // Create allocation site info. | 9732 // Create allocation site info. |
| 9867 if (mode == TRACK_ALLOCATION_SITE && | 9733 if (mode == TRACK_ALLOCATION_SITE && |
| 9868 boilerplate_object->map()->CanTrackAllocationSite()) { | 9734 boilerplate_object->map()->CanTrackAllocationSite()) { |
| 9869 elements_offset += AllocationSiteInfo::kSize; | 9735 elements_offset += AllocationSiteInfo::kSize; |
| 9870 *offset += AllocationSiteInfo::kSize; | 9736 *offset += AllocationSiteInfo::kSize; |
| 9871 HInstruction* original_boilerplate = AddInstruction(new(zone) HConstant( | 9737 HInstruction* original_boilerplate = |
| 9872 original_boilerplate_object)); | 9738 Add<HConstant>(original_boilerplate_object); |
| 9873 BuildCreateAllocationSiteInfo(target, JSArray::kSize, original_boilerplate); | 9739 BuildCreateAllocationSiteInfo(target, JSArray::kSize, original_boilerplate); |
| 9874 } | 9740 } |
| 9875 } | 9741 } |
| 9876 | 9742 |
| 9877 | 9743 |
| 9878 HValue* HOptimizedGraphBuilder::BuildEmitObjectHeader( | 9744 HValue* HOptimizedGraphBuilder::BuildEmitObjectHeader( |
| 9879 Handle<JSObject> boilerplate_object, | 9745 Handle<JSObject> boilerplate_object, |
| 9880 HInstruction* target, | 9746 HInstruction* target, |
| 9881 HInstruction* data_target, | 9747 HInstruction* data_target, |
| 9882 int object_offset, | 9748 int object_offset, |
| 9883 int elements_offset, | 9749 int elements_offset, |
| 9884 int elements_size) { | 9750 int elements_size) { |
| 9885 ASSERT(boilerplate_object->properties()->length() == 0); | 9751 ASSERT(boilerplate_object->properties()->length() == 0); |
| 9886 Zone* zone = this->zone(); | |
| 9887 HValue* result = NULL; | 9752 HValue* result = NULL; |
| 9888 | 9753 |
| 9889 HValue* object_header = | 9754 HValue* object_header = Add<HInnerAllocatedObject>(target, object_offset); |
| 9890 AddInstruction(new(zone) HInnerAllocatedObject(target, object_offset)); | |
| 9891 Handle<Map> boilerplate_object_map(boilerplate_object->map()); | 9755 Handle<Map> boilerplate_object_map(boilerplate_object->map()); |
| 9892 AddStoreMapConstant(object_header, boilerplate_object_map); | 9756 AddStoreMapConstant(object_header, boilerplate_object_map); |
| 9893 | 9757 |
| 9894 HInstruction* elements; | 9758 HInstruction* elements; |
| 9895 if (elements_size == 0) { | 9759 if (elements_size == 0) { |
| 9896 Handle<Object> elements_field = | 9760 Handle<Object> elements_field = |
| 9897 Handle<Object>(boilerplate_object->elements(), isolate()); | 9761 Handle<Object>(boilerplate_object->elements(), isolate()); |
| 9898 elements = AddInstruction(new(zone) HConstant(elements_field)); | 9762 elements = Add<HConstant>(elements_field); |
| 9899 } else { | 9763 } else { |
| 9900 if (data_target != NULL && boilerplate_object->HasFastDoubleElements()) { | 9764 if (data_target != NULL && boilerplate_object->HasFastDoubleElements()) { |
| 9901 elements = AddInstruction(new(zone) HInnerAllocatedObject( | 9765 elements = Add<HInnerAllocatedObject>(data_target, elements_offset); |
| 9902 data_target, elements_offset)); | |
| 9903 } else { | 9766 } else { |
| 9904 elements = AddInstruction(new(zone) HInnerAllocatedObject( | 9767 elements = Add<HInnerAllocatedObject>(target, elements_offset); |
| 9905 target, elements_offset)); | |
| 9906 } | 9768 } |
| 9907 result = elements; | 9769 result = elements; |
| 9908 } | 9770 } |
| 9909 AddStore(object_header, HObjectAccess::ForElementsPointer(), elements); | 9771 AddStore(object_header, HObjectAccess::ForElementsPointer(), elements); |
| 9910 | 9772 |
| 9911 Handle<Object> properties_field = | 9773 Handle<Object> properties_field = |
| 9912 Handle<Object>(boilerplate_object->properties(), isolate()); | 9774 Handle<Object>(boilerplate_object->properties(), isolate()); |
| 9913 ASSERT(*properties_field == isolate()->heap()->empty_fixed_array()); | 9775 ASSERT(*properties_field == isolate()->heap()->empty_fixed_array()); |
| 9914 HInstruction* properties = AddInstruction(new(zone) HConstant( | 9776 HInstruction* properties = Add<HConstant>(properties_field); |
| 9915 properties_field)); | |
| 9916 HObjectAccess access = HObjectAccess::ForPropertiesPointer(); | 9777 HObjectAccess access = HObjectAccess::ForPropertiesPointer(); |
| 9917 AddStore(object_header, access, properties); | 9778 AddStore(object_header, access, properties); |
| 9918 | 9779 |
| 9919 if (boilerplate_object->IsJSArray()) { | 9780 if (boilerplate_object->IsJSArray()) { |
| 9920 Handle<JSArray> boilerplate_array = | 9781 Handle<JSArray> boilerplate_array = |
| 9921 Handle<JSArray>::cast(boilerplate_object); | 9782 Handle<JSArray>::cast(boilerplate_object); |
| 9922 Handle<Object> length_field = | 9783 Handle<Object> length_field = |
| 9923 Handle<Object>(boilerplate_array->length(), isolate()); | 9784 Handle<Object>(boilerplate_array->length(), isolate()); |
| 9924 HInstruction* length = AddInstruction(new(zone) HConstant(length_field)); | 9785 HInstruction* length = Add<HConstant>(length_field); |
| 9925 | 9786 |
| 9926 ASSERT(boilerplate_array->length()->IsSmi()); | 9787 ASSERT(boilerplate_array->length()->IsSmi()); |
| 9927 Representation representation = | 9788 Representation representation = |
| 9928 IsFastElementsKind(boilerplate_array->GetElementsKind()) | 9789 IsFastElementsKind(boilerplate_array->GetElementsKind()) |
| 9929 ? Representation::Smi() : Representation::Tagged(); | 9790 ? Representation::Smi() : Representation::Tagged(); |
| 9930 AddStore(object_header, HObjectAccess::ForArrayLength(), | 9791 AddStore(object_header, HObjectAccess::ForArrayLength(), |
| 9931 length, representation); | 9792 length, representation); |
| 9932 } | 9793 } |
| 9933 | 9794 |
| 9934 return result; | 9795 return result; |
| 9935 } | 9796 } |
| 9936 | 9797 |
| 9937 | 9798 |
| 9938 void HOptimizedGraphBuilder::BuildEmitInObjectProperties( | 9799 void HOptimizedGraphBuilder::BuildEmitInObjectProperties( |
| 9939 Handle<JSObject> boilerplate_object, | 9800 Handle<JSObject> boilerplate_object, |
| 9940 Handle<JSObject> original_boilerplate_object, | 9801 Handle<JSObject> original_boilerplate_object, |
| 9941 HValue* object_properties, | 9802 HValue* object_properties, |
| 9942 HInstruction* target, | 9803 HInstruction* target, |
| 9943 int* offset, | 9804 int* offset, |
| 9944 HInstruction* data_target, | 9805 HInstruction* data_target, |
| 9945 int* data_offset) { | 9806 int* data_offset) { |
| 9946 Zone* zone = this->zone(); | |
| 9947 Handle<DescriptorArray> descriptors( | 9807 Handle<DescriptorArray> descriptors( |
| 9948 boilerplate_object->map()->instance_descriptors()); | 9808 boilerplate_object->map()->instance_descriptors()); |
| 9949 int limit = boilerplate_object->map()->NumberOfOwnDescriptors(); | 9809 int limit = boilerplate_object->map()->NumberOfOwnDescriptors(); |
| 9950 | 9810 |
| 9951 int copied_fields = 0; | 9811 int copied_fields = 0; |
| 9952 for (int i = 0; i < limit; i++) { | 9812 for (int i = 0; i < limit; i++) { |
| 9953 PropertyDetails details = descriptors->GetDetails(i); | 9813 PropertyDetails details = descriptors->GetDetails(i); |
| 9954 if (details.type() != FIELD) continue; | 9814 if (details.type() != FIELD) continue; |
| 9955 copied_fields++; | 9815 copied_fields++; |
| 9956 int index = descriptors->GetFieldIndex(i); | 9816 int index = descriptors->GetFieldIndex(i); |
| 9957 int property_offset = boilerplate_object->GetInObjectPropertyOffset(index); | 9817 int property_offset = boilerplate_object->GetInObjectPropertyOffset(index); |
| 9958 Handle<Name> name(descriptors->GetKey(i)); | 9818 Handle<Name> name(descriptors->GetKey(i)); |
| 9959 Handle<Object> value = | 9819 Handle<Object> value = |
| 9960 Handle<Object>(boilerplate_object->InObjectPropertyAt(index), | 9820 Handle<Object>(boilerplate_object->InObjectPropertyAt(index), |
| 9961 isolate()); | 9821 isolate()); |
| 9962 | 9822 |
| 9963 // The access for the store depends on the type of the boilerplate. | 9823 // The access for the store depends on the type of the boilerplate. |
| 9964 HObjectAccess access = boilerplate_object->IsJSArray() ? | 9824 HObjectAccess access = boilerplate_object->IsJSArray() ? |
| 9965 HObjectAccess::ForJSArrayOffset(property_offset) : | 9825 HObjectAccess::ForJSArrayOffset(property_offset) : |
| 9966 HObjectAccess::ForJSObjectOffset(property_offset); | 9826 HObjectAccess::ForJSObjectOffset(property_offset); |
| 9967 | 9827 |
| 9968 if (value->IsJSObject()) { | 9828 if (value->IsJSObject()) { |
| 9969 Handle<JSObject> value_object = Handle<JSObject>::cast(value); | 9829 Handle<JSObject> value_object = Handle<JSObject>::cast(value); |
| 9970 Handle<JSObject> original_value_object = Handle<JSObject>::cast( | 9830 Handle<JSObject> original_value_object = Handle<JSObject>::cast( |
| 9971 Handle<Object>(original_boilerplate_object->InObjectPropertyAt(index), | 9831 Handle<Object>(original_boilerplate_object->InObjectPropertyAt(index), |
| 9972 isolate())); | 9832 isolate())); |
| 9973 HInstruction* value_instruction = | 9833 HInstruction* value_instruction = Add<HInnerAllocatedObject>(target, |
| 9974 AddInstruction(new(zone) HInnerAllocatedObject(target, *offset)); | 9834 *offset); |
| 9975 | 9835 |
| 9976 AddStore(object_properties, access, value_instruction); | 9836 AddStore(object_properties, access, value_instruction); |
| 9977 | 9837 |
| 9978 BuildEmitDeepCopy(value_object, original_value_object, target, | 9838 BuildEmitDeepCopy(value_object, original_value_object, target, |
| 9979 offset, data_target, data_offset, DONT_TRACK_ALLOCATION_SITE); | 9839 offset, data_target, data_offset, DONT_TRACK_ALLOCATION_SITE); |
| 9980 } else { | 9840 } else { |
| 9981 Representation representation = details.representation(); | 9841 Representation representation = details.representation(); |
| 9982 HInstruction* value_instruction = | 9842 HInstruction* value_instruction = Add<HConstant>(value); |
| 9983 AddInstruction(new(zone) HConstant(value)); | |
| 9984 | 9843 |
| 9985 if (representation.IsDouble()) { | 9844 if (representation.IsDouble()) { |
| 9986 // Allocate a HeapNumber box and store the value into it. | 9845 // Allocate a HeapNumber box and store the value into it. |
| 9987 HInstruction* double_box; | 9846 HInstruction* double_box; |
| 9988 if (data_target != NULL) { | 9847 if (data_target != NULL) { |
| 9989 double_box = AddInstruction(new(zone) HInnerAllocatedObject( | 9848 double_box = Add<HInnerAllocatedObject>(data_target, *data_offset); |
| 9990 data_target, *data_offset)); | |
| 9991 *data_offset += HeapNumber::kSize; | 9849 *data_offset += HeapNumber::kSize; |
| 9992 } else { | 9850 } else { |
| 9993 double_box = AddInstruction(new(zone) HInnerAllocatedObject( | 9851 double_box = Add<HInnerAllocatedObject>(target, *offset); |
| 9994 target, *offset)); | |
| 9995 *offset += HeapNumber::kSize; | 9852 *offset += HeapNumber::kSize; |
| 9996 } | 9853 } |
| 9997 AddStoreMapConstant(double_box, | 9854 AddStoreMapConstant(double_box, |
| 9998 isolate()->factory()->heap_number_map()); | 9855 isolate()->factory()->heap_number_map()); |
| 9999 AddStore(double_box, HObjectAccess::ForHeapNumberValue(), | 9856 AddStore(double_box, HObjectAccess::ForHeapNumberValue(), |
| 10000 value_instruction, Representation::Double()); | 9857 value_instruction, Representation::Double()); |
| 10001 value_instruction = double_box; | 9858 value_instruction = double_box; |
| 10002 } | 9859 } |
| 10003 | 9860 |
| 10004 AddStore(object_properties, access, value_instruction); | 9861 AddStore(object_properties, access, value_instruction); |
| 10005 } | 9862 } |
| 10006 } | 9863 } |
| 10007 | 9864 |
| 10008 int inobject_properties = boilerplate_object->map()->inobject_properties(); | 9865 int inobject_properties = boilerplate_object->map()->inobject_properties(); |
| 10009 HInstruction* value_instruction = AddInstruction(new(zone) | 9866 HInstruction* value_instruction = |
| 10010 HConstant(isolate()->factory()->one_pointer_filler_map())); | 9867 Add<HConstant>(isolate()->factory()->one_pointer_filler_map()); |
| 10011 for (int i = copied_fields; i < inobject_properties; i++) { | 9868 for (int i = copied_fields; i < inobject_properties; i++) { |
| 10012 ASSERT(boilerplate_object->IsJSObject()); | 9869 ASSERT(boilerplate_object->IsJSObject()); |
| 10013 int property_offset = boilerplate_object->GetInObjectPropertyOffset(i); | 9870 int property_offset = boilerplate_object->GetInObjectPropertyOffset(i); |
| 10014 HObjectAccess access = HObjectAccess::ForJSObjectOffset(property_offset); | 9871 HObjectAccess access = HObjectAccess::ForJSObjectOffset(property_offset); |
| 10015 AddStore(object_properties, access, value_instruction); | 9872 AddStore(object_properties, access, value_instruction); |
| 10016 } | 9873 } |
| 10017 } | 9874 } |
| 10018 | 9875 |
| 10019 | 9876 |
| 10020 void HOptimizedGraphBuilder::BuildEmitElements( | 9877 void HOptimizedGraphBuilder::BuildEmitElements( |
| 10021 Handle<FixedArrayBase> elements, | 9878 Handle<FixedArrayBase> elements, |
| 10022 Handle<FixedArrayBase> original_elements, | 9879 Handle<FixedArrayBase> original_elements, |
| 10023 ElementsKind kind, | 9880 ElementsKind kind, |
| 10024 HValue* object_elements, | 9881 HValue* object_elements, |
| 10025 HInstruction* target, | 9882 HInstruction* target, |
| 10026 int* offset, | 9883 int* offset, |
| 10027 HInstruction* data_target, | 9884 HInstruction* data_target, |
| 10028 int* data_offset) { | 9885 int* data_offset) { |
| 10029 Zone* zone = this->zone(); | |
| 10030 | |
| 10031 int elements_length = elements->length(); | 9886 int elements_length = elements->length(); |
| 10032 HValue* object_elements_length = | 9887 HValue* object_elements_length = Add<HConstant>(elements_length); |
| 10033 AddInstruction(new(zone) HConstant(elements_length)); | |
| 10034 | 9888 |
| 10035 BuildInitializeElementsHeader(object_elements, kind, object_elements_length); | 9889 BuildInitializeElementsHeader(object_elements, kind, object_elements_length); |
| 10036 | 9890 |
| 10037 // Copy elements backing store content. | 9891 // Copy elements backing store content. |
| 10038 if (elements->IsFixedDoubleArray()) { | 9892 if (elements->IsFixedDoubleArray()) { |
| 10039 BuildEmitFixedDoubleArray(elements, kind, object_elements); | 9893 BuildEmitFixedDoubleArray(elements, kind, object_elements); |
| 10040 } else if (elements->IsFixedArray()) { | 9894 } else if (elements->IsFixedArray()) { |
| 10041 BuildEmitFixedArray(elements, original_elements, kind, object_elements, | 9895 BuildEmitFixedArray(elements, original_elements, kind, object_elements, |
| 10042 target, offset, data_target, data_offset); | 9896 target, offset, data_target, data_offset); |
| 10043 } else { | 9897 } else { |
| 10044 UNREACHABLE(); | 9898 UNREACHABLE(); |
| 10045 } | 9899 } |
| 10046 } | 9900 } |
| 10047 | 9901 |
| 10048 | 9902 |
| 10049 void HOptimizedGraphBuilder::BuildEmitFixedDoubleArray( | 9903 void HOptimizedGraphBuilder::BuildEmitFixedDoubleArray( |
| 10050 Handle<FixedArrayBase> elements, | 9904 Handle<FixedArrayBase> elements, |
| 10051 ElementsKind kind, | 9905 ElementsKind kind, |
| 10052 HValue* object_elements) { | 9906 HValue* object_elements) { |
| 10053 Zone* zone = this->zone(); | 9907 HInstruction* boilerplate_elements = Add<HConstant>(elements); |
| 10054 HInstruction* boilerplate_elements = | |
| 10055 AddInstruction(new(zone) HConstant(elements)); | |
| 10056 int elements_length = elements->length(); | 9908 int elements_length = elements->length(); |
| 10057 for (int i = 0; i < elements_length; i++) { | 9909 for (int i = 0; i < elements_length; i++) { |
| 10058 HValue* key_constant = AddInstruction(new(zone) HConstant(i)); | 9910 HValue* key_constant = Add<HConstant>(i); |
| 10059 HInstruction* value_instruction = | 9911 HInstruction* value_instruction = |
| 10060 AddInstruction(new(zone) HLoadKeyed( | 9912 Add<HLoadKeyed>(boilerplate_elements, key_constant, |
| 10061 boilerplate_elements, key_constant, NULL, kind, ALLOW_RETURN_HOLE)); | 9913 static_cast<HValue*>(NULL), kind, |
| 10062 HInstruction* store = AddInstruction(new(zone) HStoreKeyed( | 9914 ALLOW_RETURN_HOLE); |
| 10063 object_elements, key_constant, value_instruction, kind)); | 9915 HInstruction* store = Add<HStoreKeyed>(object_elements, key_constant, |
| 9916 value_instruction, kind); |
| 10064 store->SetFlag(HValue::kAllowUndefinedAsNaN); | 9917 store->SetFlag(HValue::kAllowUndefinedAsNaN); |
| 10065 } | 9918 } |
| 10066 } | 9919 } |
| 10067 | 9920 |
| 10068 | 9921 |
| 10069 void HOptimizedGraphBuilder::BuildEmitFixedArray( | 9922 void HOptimizedGraphBuilder::BuildEmitFixedArray( |
| 10070 Handle<FixedArrayBase> elements, | 9923 Handle<FixedArrayBase> elements, |
| 10071 Handle<FixedArrayBase> original_elements, | 9924 Handle<FixedArrayBase> original_elements, |
| 10072 ElementsKind kind, | 9925 ElementsKind kind, |
| 10073 HValue* object_elements, | 9926 HValue* object_elements, |
| 10074 HInstruction* target, | 9927 HInstruction* target, |
| 10075 int* offset, | 9928 int* offset, |
| 10076 HInstruction* data_target, | 9929 HInstruction* data_target, |
| 10077 int* data_offset) { | 9930 int* data_offset) { |
| 10078 Zone* zone = this->zone(); | 9931 HInstruction* boilerplate_elements = Add<HConstant>(elements); |
| 10079 HInstruction* boilerplate_elements = | |
| 10080 AddInstruction(new(zone) HConstant(elements)); | |
| 10081 int elements_length = elements->length(); | 9932 int elements_length = elements->length(); |
| 10082 Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements); | 9933 Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements); |
| 10083 Handle<FixedArray> original_fast_elements = | 9934 Handle<FixedArray> original_fast_elements = |
| 10084 Handle<FixedArray>::cast(original_elements); | 9935 Handle<FixedArray>::cast(original_elements); |
| 10085 for (int i = 0; i < elements_length; i++) { | 9936 for (int i = 0; i < elements_length; i++) { |
| 10086 Handle<Object> value(fast_elements->get(i), isolate()); | 9937 Handle<Object> value(fast_elements->get(i), isolate()); |
| 10087 HValue* key_constant = AddInstruction(new(zone) HConstant(i)); | 9938 HValue* key_constant = Add<HConstant>(i); |
| 10088 if (value->IsJSObject()) { | 9939 if (value->IsJSObject()) { |
| 10089 Handle<JSObject> value_object = Handle<JSObject>::cast(value); | 9940 Handle<JSObject> value_object = Handle<JSObject>::cast(value); |
| 10090 Handle<JSObject> original_value_object = Handle<JSObject>::cast( | 9941 Handle<JSObject> original_value_object = Handle<JSObject>::cast( |
| 10091 Handle<Object>(original_fast_elements->get(i), isolate())); | 9942 Handle<Object>(original_fast_elements->get(i), isolate())); |
| 10092 HInstruction* value_instruction = | 9943 HInstruction* value_instruction = Add<HInnerAllocatedObject>(target, |
| 10093 AddInstruction(new(zone) HInnerAllocatedObject(target, *offset)); | 9944 *offset); |
| 10094 AddInstruction(new(zone) HStoreKeyed( | 9945 Add<HStoreKeyed>(object_elements, key_constant, value_instruction, kind); |
| 10095 object_elements, key_constant, value_instruction, kind)); | |
| 10096 BuildEmitDeepCopy(value_object, original_value_object, target, | 9946 BuildEmitDeepCopy(value_object, original_value_object, target, |
| 10097 offset, data_target, data_offset, DONT_TRACK_ALLOCATION_SITE); | 9947 offset, data_target, data_offset, DONT_TRACK_ALLOCATION_SITE); |
| 10098 } else { | 9948 } else { |
| 10099 HInstruction* value_instruction = | 9949 HInstruction* value_instruction = |
| 10100 AddInstruction(new(zone) HLoadKeyed( | 9950 Add<HLoadKeyed>(boilerplate_elements, key_constant, |
| 10101 boilerplate_elements, key_constant, NULL, kind, | 9951 static_cast<HValue*>(NULL), kind, |
| 10102 ALLOW_RETURN_HOLE)); | 9952 ALLOW_RETURN_HOLE); |
| 10103 AddInstruction(new(zone) HStoreKeyed( | 9953 Add<HStoreKeyed>(object_elements, key_constant, value_instruction, kind); |
| 10104 object_elements, key_constant, value_instruction, kind)); | |
| 10105 } | 9954 } |
| 10106 } | 9955 } |
| 10107 } | 9956 } |
| 10108 | 9957 |
| 10109 void HOptimizedGraphBuilder::VisitThisFunction(ThisFunction* expr) { | 9958 void HOptimizedGraphBuilder::VisitThisFunction(ThisFunction* expr) { |
| 10110 ASSERT(!HasStackOverflow()); | 9959 ASSERT(!HasStackOverflow()); |
| 10111 ASSERT(current_block() != NULL); | 9960 ASSERT(current_block() != NULL); |
| 10112 ASSERT(current_block()->HasPredecessor()); | 9961 ASSERT(current_block()->HasPredecessor()); |
| 10113 HInstruction* instr = BuildThisFunction(); | 9962 HInstruction* instr = BuildThisFunction(); |
| 10114 return ast_context()->ReturnInstruction(instr, expr->id()); | 9963 return ast_context()->ReturnInstruction(instr, expr->id()); |
| 10115 } | 9964 } |
| 10116 | 9965 |
| 10117 | 9966 |
| 10118 void HOptimizedGraphBuilder::VisitDeclarations( | 9967 void HOptimizedGraphBuilder::VisitDeclarations( |
| 10119 ZoneList<Declaration*>* declarations) { | 9968 ZoneList<Declaration*>* declarations) { |
| 10120 ASSERT(globals_.is_empty()); | 9969 ASSERT(globals_.is_empty()); |
| 10121 AstVisitor::VisitDeclarations(declarations); | 9970 AstVisitor::VisitDeclarations(declarations); |
| 10122 if (!globals_.is_empty()) { | 9971 if (!globals_.is_empty()) { |
| 10123 Handle<FixedArray> array = | 9972 Handle<FixedArray> array = |
| 10124 isolate()->factory()->NewFixedArray(globals_.length(), TENURED); | 9973 isolate()->factory()->NewFixedArray(globals_.length(), TENURED); |
| 10125 for (int i = 0; i < globals_.length(); ++i) array->set(i, *globals_.at(i)); | 9974 for (int i = 0; i < globals_.length(); ++i) array->set(i, *globals_.at(i)); |
| 10126 int flags = DeclareGlobalsEvalFlag::encode(current_info()->is_eval()) | | 9975 int flags = DeclareGlobalsEvalFlag::encode(current_info()->is_eval()) | |
| 10127 DeclareGlobalsNativeFlag::encode(current_info()->is_native()) | | 9976 DeclareGlobalsNativeFlag::encode(current_info()->is_native()) | |
| 10128 DeclareGlobalsLanguageMode::encode(current_info()->language_mode()); | 9977 DeclareGlobalsLanguageMode::encode(current_info()->language_mode()); |
| 10129 HInstruction* result = new(zone()) HDeclareGlobals( | 9978 Add<HDeclareGlobals>(environment()->LookupContext(), array, flags); |
| 10130 environment()->LookupContext(), array, flags); | |
| 10131 AddInstruction(result); | |
| 10132 globals_.Clear(); | 9979 globals_.Clear(); |
| 10133 } | 9980 } |
| 10134 } | 9981 } |
| 10135 | 9982 |
| 10136 | 9983 |
| 10137 void HOptimizedGraphBuilder::VisitVariableDeclaration( | 9984 void HOptimizedGraphBuilder::VisitVariableDeclaration( |
| 10138 VariableDeclaration* declaration) { | 9985 VariableDeclaration* declaration) { |
| 10139 VariableProxy* proxy = declaration->proxy(); | 9986 VariableProxy* proxy = declaration->proxy(); |
| 10140 VariableMode mode = declaration->mode(); | 9987 VariableMode mode = declaration->mode(); |
| 10141 Variable* variable = proxy->var(); | 9988 Variable* variable = proxy->var(); |
| 10142 bool hole_init = mode == CONST || mode == CONST_HARMONY || mode == LET; | 9989 bool hole_init = mode == CONST || mode == CONST_HARMONY || mode == LET; |
| 10143 switch (variable->location()) { | 9990 switch (variable->location()) { |
| 10144 case Variable::UNALLOCATED: | 9991 case Variable::UNALLOCATED: |
| 10145 globals_.Add(variable->name(), zone()); | 9992 globals_.Add(variable->name(), zone()); |
| 10146 globals_.Add(variable->binding_needs_init() | 9993 globals_.Add(variable->binding_needs_init() |
| 10147 ? isolate()->factory()->the_hole_value() | 9994 ? isolate()->factory()->the_hole_value() |
| 10148 : isolate()->factory()->undefined_value(), zone()); | 9995 : isolate()->factory()->undefined_value(), zone()); |
| 10149 return; | 9996 return; |
| 10150 case Variable::PARAMETER: | 9997 case Variable::PARAMETER: |
| 10151 case Variable::LOCAL: | 9998 case Variable::LOCAL: |
| 10152 if (hole_init) { | 9999 if (hole_init) { |
| 10153 HValue* value = graph()->GetConstantHole(); | 10000 HValue* value = graph()->GetConstantHole(); |
| 10154 environment()->Bind(variable, value); | 10001 environment()->Bind(variable, value); |
| 10155 } | 10002 } |
| 10156 break; | 10003 break; |
| 10157 case Variable::CONTEXT: | 10004 case Variable::CONTEXT: |
| 10158 if (hole_init) { | 10005 if (hole_init) { |
| 10159 HValue* value = graph()->GetConstantHole(); | 10006 HValue* value = graph()->GetConstantHole(); |
| 10160 HValue* context = environment()->LookupContext(); | 10007 HValue* context = environment()->LookupContext(); |
| 10161 HStoreContextSlot* store = new(zone()) HStoreContextSlot( | 10008 HStoreContextSlot* store = Add<HStoreContextSlot>( |
| 10162 context, variable->index(), HStoreContextSlot::kNoCheck, value); | 10009 context, variable->index(), HStoreContextSlot::kNoCheck, value); |
| 10163 AddInstruction(store); | |
| 10164 if (store->HasObservableSideEffects()) { | 10010 if (store->HasObservableSideEffects()) { |
| 10165 AddSimulate(proxy->id(), REMOVABLE_SIMULATE); | 10011 AddSimulate(proxy->id(), REMOVABLE_SIMULATE); |
| 10166 } | 10012 } |
| 10167 } | 10013 } |
| 10168 break; | 10014 break; |
| 10169 case Variable::LOOKUP: | 10015 case Variable::LOOKUP: |
| 10170 return Bailout("unsupported lookup slot in declaration"); | 10016 return Bailout("unsupported lookup slot in declaration"); |
| 10171 } | 10017 } |
| 10172 } | 10018 } |
| 10173 | 10019 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 10190 case Variable::LOCAL: { | 10036 case Variable::LOCAL: { |
| 10191 CHECK_ALIVE(VisitForValue(declaration->fun())); | 10037 CHECK_ALIVE(VisitForValue(declaration->fun())); |
| 10192 HValue* value = Pop(); | 10038 HValue* value = Pop(); |
| 10193 BindIfLive(variable, value); | 10039 BindIfLive(variable, value); |
| 10194 break; | 10040 break; |
| 10195 } | 10041 } |
| 10196 case Variable::CONTEXT: { | 10042 case Variable::CONTEXT: { |
| 10197 CHECK_ALIVE(VisitForValue(declaration->fun())); | 10043 CHECK_ALIVE(VisitForValue(declaration->fun())); |
| 10198 HValue* value = Pop(); | 10044 HValue* value = Pop(); |
| 10199 HValue* context = environment()->LookupContext(); | 10045 HValue* context = environment()->LookupContext(); |
| 10200 HStoreContextSlot* store = new(zone()) HStoreContextSlot( | 10046 HStoreContextSlot* store = Add<HStoreContextSlot>( |
| 10201 context, variable->index(), HStoreContextSlot::kNoCheck, value); | 10047 context, variable->index(), HStoreContextSlot::kNoCheck, value); |
| 10202 AddInstruction(store); | |
| 10203 if (store->HasObservableSideEffects()) { | 10048 if (store->HasObservableSideEffects()) { |
| 10204 AddSimulate(proxy->id(), REMOVABLE_SIMULATE); | 10049 AddSimulate(proxy->id(), REMOVABLE_SIMULATE); |
| 10205 } | 10050 } |
| 10206 break; | 10051 break; |
| 10207 } | 10052 } |
| 10208 case Variable::LOOKUP: | 10053 case Variable::LOOKUP: |
| 10209 return Bailout("unsupported lookup slot in declaration"); | 10054 return Bailout("unsupported lookup slot in declaration"); |
| 10210 } | 10055 } |
| 10211 } | 10056 } |
| 10212 | 10057 |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10364 } | 10209 } |
| 10365 | 10210 |
| 10366 | 10211 |
| 10367 // Support for arguments.length and arguments[?]. | 10212 // Support for arguments.length and arguments[?]. |
| 10368 void HOptimizedGraphBuilder::GenerateArgumentsLength(CallRuntime* call) { | 10213 void HOptimizedGraphBuilder::GenerateArgumentsLength(CallRuntime* call) { |
| 10369 // Our implementation of arguments (based on this stack frame or an | 10214 // Our implementation of arguments (based on this stack frame or an |
| 10370 // adapter below it) does not work for inlined functions. This runtime | 10215 // adapter below it) does not work for inlined functions. This runtime |
| 10371 // function is blacklisted by AstNode::IsInlineable. | 10216 // function is blacklisted by AstNode::IsInlineable. |
| 10372 ASSERT(function_state()->outer() == NULL); | 10217 ASSERT(function_state()->outer() == NULL); |
| 10373 ASSERT(call->arguments()->length() == 0); | 10218 ASSERT(call->arguments()->length() == 0); |
| 10374 HInstruction* elements = AddInstruction( | 10219 HInstruction* elements = Add<HArgumentsElements>(false); |
| 10375 new(zone()) HArgumentsElements(false)); | |
| 10376 HArgumentsLength* result = new(zone()) HArgumentsLength(elements); | 10220 HArgumentsLength* result = new(zone()) HArgumentsLength(elements); |
| 10377 return ast_context()->ReturnInstruction(result, call->id()); | 10221 return ast_context()->ReturnInstruction(result, call->id()); |
| 10378 } | 10222 } |
| 10379 | 10223 |
| 10380 | 10224 |
| 10381 void HOptimizedGraphBuilder::GenerateArguments(CallRuntime* call) { | 10225 void HOptimizedGraphBuilder::GenerateArguments(CallRuntime* call) { |
| 10382 // Our implementation of arguments (based on this stack frame or an | 10226 // Our implementation of arguments (based on this stack frame or an |
| 10383 // adapter below it) does not work for inlined functions. This runtime | 10227 // adapter below it) does not work for inlined functions. This runtime |
| 10384 // function is blacklisted by AstNode::IsInlineable. | 10228 // function is blacklisted by AstNode::IsInlineable. |
| 10385 ASSERT(function_state()->outer() == NULL); | 10229 ASSERT(function_state()->outer() == NULL); |
| 10386 ASSERT(call->arguments()->length() == 1); | 10230 ASSERT(call->arguments()->length() == 1); |
| 10387 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 10231 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
| 10388 HValue* index = Pop(); | 10232 HValue* index = Pop(); |
| 10389 HInstruction* elements = AddInstruction( | 10233 HInstruction* elements = Add<HArgumentsElements>(false); |
| 10390 new(zone()) HArgumentsElements(false)); | 10234 HInstruction* length = Add<HArgumentsLength>(elements); |
| 10391 HInstruction* length = AddInstruction(new(zone()) HArgumentsLength(elements)); | |
| 10392 HInstruction* checked_index = Add<HBoundsCheck>(index, length); | 10235 HInstruction* checked_index = Add<HBoundsCheck>(index, length); |
| 10393 HAccessArgumentsAt* result = | 10236 HAccessArgumentsAt* result = |
| 10394 new(zone()) HAccessArgumentsAt(elements, length, checked_index); | 10237 new(zone()) HAccessArgumentsAt(elements, length, checked_index); |
| 10395 return ast_context()->ReturnInstruction(result, call->id()); | 10238 return ast_context()->ReturnInstruction(result, call->id()); |
| 10396 } | 10239 } |
| 10397 | 10240 |
| 10398 | 10241 |
| 10399 // Support for accessing the class and value fields of an object. | 10242 // Support for accessing the class and value fields of an object. |
| 10400 void HOptimizedGraphBuilder::GenerateClassOf(CallRuntime* call) { | 10243 void HOptimizedGraphBuilder::GenerateClassOf(CallRuntime* call) { |
| 10401 // The special form detected by IsClassOfTest is detected before we get here | 10244 // The special form detected by IsClassOfTest is detected before we get here |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10546 | 10389 |
| 10547 void HOptimizedGraphBuilder::GenerateLog(CallRuntime* call) { | 10390 void HOptimizedGraphBuilder::GenerateLog(CallRuntime* call) { |
| 10548 // %_Log is ignored in optimized code. | 10391 // %_Log is ignored in optimized code. |
| 10549 return ast_context()->ReturnValue(graph()->GetConstantUndefined()); | 10392 return ast_context()->ReturnValue(graph()->GetConstantUndefined()); |
| 10550 } | 10393 } |
| 10551 | 10394 |
| 10552 | 10395 |
| 10553 // Fast support for Math.random(). | 10396 // Fast support for Math.random(). |
| 10554 void HOptimizedGraphBuilder::GenerateRandomHeapNumber(CallRuntime* call) { | 10397 void HOptimizedGraphBuilder::GenerateRandomHeapNumber(CallRuntime* call) { |
| 10555 HValue* context = environment()->LookupContext(); | 10398 HValue* context = environment()->LookupContext(); |
| 10556 HGlobalObject* global_object = new(zone()) HGlobalObject(context); | 10399 HGlobalObject* global_object = Add<HGlobalObject>(context); |
| 10557 AddInstruction(global_object); | |
| 10558 HRandom* result = new(zone()) HRandom(global_object); | 10400 HRandom* result = new(zone()) HRandom(global_object); |
| 10559 return ast_context()->ReturnInstruction(result, call->id()); | 10401 return ast_context()->ReturnInstruction(result, call->id()); |
| 10560 } | 10402 } |
| 10561 | 10403 |
| 10562 | 10404 |
| 10563 // Fast support for StringAdd. | 10405 // Fast support for StringAdd. |
| 10564 void HOptimizedGraphBuilder::GenerateStringAdd(CallRuntime* call) { | 10406 void HOptimizedGraphBuilder::GenerateStringAdd(CallRuntime* call) { |
| 10565 ASSERT_EQ(2, call->arguments()->length()); | 10407 ASSERT_EQ(2, call->arguments()->length()); |
| 10566 CHECK_ALIVE(VisitArgumentList(call->arguments())); | 10408 CHECK_ALIVE(VisitArgumentList(call->arguments())); |
| 10567 HValue* context = environment()->LookupContext(); | 10409 HValue* context = environment()->LookupContext(); |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10653 HHasInstanceTypeAndBranch* typecheck = | 10495 HHasInstanceTypeAndBranch* typecheck = |
| 10654 new(zone()) HHasInstanceTypeAndBranch(function, JS_FUNCTION_TYPE); | 10496 new(zone()) HHasInstanceTypeAndBranch(function, JS_FUNCTION_TYPE); |
| 10655 HBasicBlock* if_jsfunction = graph()->CreateBasicBlock(); | 10497 HBasicBlock* if_jsfunction = graph()->CreateBasicBlock(); |
| 10656 HBasicBlock* if_nonfunction = graph()->CreateBasicBlock(); | 10498 HBasicBlock* if_nonfunction = graph()->CreateBasicBlock(); |
| 10657 HBasicBlock* join = graph()->CreateBasicBlock(); | 10499 HBasicBlock* join = graph()->CreateBasicBlock(); |
| 10658 typecheck->SetSuccessorAt(0, if_jsfunction); | 10500 typecheck->SetSuccessorAt(0, if_jsfunction); |
| 10659 typecheck->SetSuccessorAt(1, if_nonfunction); | 10501 typecheck->SetSuccessorAt(1, if_nonfunction); |
| 10660 current_block()->Finish(typecheck); | 10502 current_block()->Finish(typecheck); |
| 10661 | 10503 |
| 10662 set_current_block(if_jsfunction); | 10504 set_current_block(if_jsfunction); |
| 10663 HInstruction* invoke_result = AddInstruction( | 10505 HInstruction* invoke_result = |
| 10664 new(zone()) HInvokeFunction(context, function, arg_count)); | 10506 Add<HInvokeFunction>(context, function, arg_count); |
| 10665 Drop(arg_count); | 10507 Drop(arg_count); |
| 10666 Push(invoke_result); | 10508 Push(invoke_result); |
| 10667 if_jsfunction->Goto(join); | 10509 if_jsfunction->Goto(join); |
| 10668 | 10510 |
| 10669 set_current_block(if_nonfunction); | 10511 set_current_block(if_nonfunction); |
| 10670 HInstruction* call_result = AddInstruction( | 10512 HInstruction* call_result = Add<HCallFunction>(context, function, arg_count); |
| 10671 new(zone()) HCallFunction(context, function, arg_count)); | |
| 10672 Drop(arg_count); | 10513 Drop(arg_count); |
| 10673 Push(call_result); | 10514 Push(call_result); |
| 10674 if_nonfunction->Goto(join); | 10515 if_nonfunction->Goto(join); |
| 10675 | 10516 |
| 10676 set_current_block(join); | 10517 set_current_block(join); |
| 10677 join->SetJoinId(call->id()); | 10518 join->SetJoinId(call->id()); |
| 10678 return ast_context()->ReturnValue(Pop()); | 10519 return ast_context()->ReturnValue(Pop()); |
| 10679 } | 10520 } |
| 10680 | 10521 |
| 10681 | 10522 |
| (...skipping 708 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11390 if (ShouldProduceTraceOutput()) { | 11231 if (ShouldProduceTraceOutput()) { |
| 11391 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 11232 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
| 11392 } | 11233 } |
| 11393 | 11234 |
| 11394 #ifdef DEBUG | 11235 #ifdef DEBUG |
| 11395 graph_->Verify(false); // No full verify. | 11236 graph_->Verify(false); // No full verify. |
| 11396 #endif | 11237 #endif |
| 11397 } | 11238 } |
| 11398 | 11239 |
| 11399 } } // namespace v8::internal | 11240 } } // namespace v8::internal |
| OLD | NEW |