Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(23)

Side by Side Diff: src/code-stubs-hydrogen.cc

Issue 157503002: A64: Synchronize with r18444. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/code-stubs.cc ('k') | src/codegen.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 282 matching lines...) Expand 10 before | Expand all | Expand 10 after
293 } 293 }
294 ElapsedTimer timer; 294 ElapsedTimer timer;
295 if (FLAG_profile_hydrogen_code_stub_compilation) { 295 if (FLAG_profile_hydrogen_code_stub_compilation) {
296 timer.Start(); 296 timer.Start();
297 } 297 }
298 CodeStubGraphBuilder<Stub> builder(isolate, stub); 298 CodeStubGraphBuilder<Stub> builder(isolate, stub);
299 LChunk* chunk = OptimizeGraph(builder.CreateGraph()); 299 LChunk* chunk = OptimizeGraph(builder.CreateGraph());
300 Handle<Code> code = chunk->Codegen(); 300 Handle<Code> code = chunk->Codegen();
301 if (FLAG_profile_hydrogen_code_stub_compilation) { 301 if (FLAG_profile_hydrogen_code_stub_compilation) {
302 double ms = timer.Elapsed().InMillisecondsF(); 302 double ms = timer.Elapsed().InMillisecondsF();
303 PrintF("[Lazy compilation of %s took %0.3f ms]\n", *stub->GetName(), ms); 303 PrintF("[Lazy compilation of %s took %0.3f ms]\n",
304 stub->GetName().get(), ms);
304 } 305 }
305 return code; 306 return code;
306 } 307 }
307 308
308 309
309 template <> 310 template <>
310 HValue* CodeStubGraphBuilder<ToNumberStub>::BuildCodeStub() { 311 HValue* CodeStubGraphBuilder<ToNumberStub>::BuildCodeStub() {
311 HValue* value = GetParameter(0); 312 HValue* value = GetParameter(0);
312 313
313 // Check if the parameter is already a SMI or heap number. 314 // Check if the parameter is already a SMI or heap number.
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
452 HValue* boilerplate_size = Add<HLoadNamedField>( 453 HValue* boilerplate_size = Add<HLoadNamedField>(
453 boilerplate_map, HObjectAccess::ForMapInstanceSize()); 454 boilerplate_map, HObjectAccess::ForMapInstanceSize());
454 HValue* size_in_words = Add<HConstant>(object_size >> kPointerSizeLog2); 455 HValue* size_in_words = Add<HConstant>(object_size >> kPointerSizeLog2);
455 checker.If<HCompareNumericAndBranch>(boilerplate_size, 456 checker.If<HCompareNumericAndBranch>(boilerplate_size,
456 size_in_words, Token::EQ); 457 size_in_words, Token::EQ);
457 checker.Then(); 458 checker.Then();
458 459
459 HValue* size_in_bytes = Add<HConstant>(size); 460 HValue* size_in_bytes = Add<HConstant>(size);
460 461
461 HInstruction* object = Add<HAllocate>(size_in_bytes, HType::JSObject(), 462 HInstruction* object = Add<HAllocate>(size_in_bytes, HType::JSObject(),
462 isolate()->heap()->GetPretenureMode(), JS_OBJECT_TYPE); 463 NOT_TENURED, JS_OBJECT_TYPE);
463 464
464 for (int i = 0; i < object_size; i += kPointerSize) { 465 for (int i = 0; i < object_size; i += kPointerSize) {
465 HObjectAccess access = HObjectAccess::ForJSObjectOffset(i); 466 HObjectAccess access = HObjectAccess::ForJSObjectOffset(i);
466 Add<HStoreNamedField>(object, access, 467 Add<HStoreNamedField>(object, access,
467 Add<HLoadNamedField>(boilerplate, access)); 468 Add<HLoadNamedField>(boilerplate, access));
468 } 469 }
469 470
470 ASSERT(FLAG_allocation_site_pretenuring || (size == object_size)); 471 ASSERT(FLAG_allocation_site_pretenuring || (size == object_size));
471 if (FLAG_allocation_site_pretenuring) { 472 if (FLAG_allocation_site_pretenuring) {
472 BuildCreateAllocationMemento( 473 BuildCreateAllocationMemento(
(...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after
903 HValue* right = GetParameter(BinaryOpICStub::kRight); 904 HValue* right = GetParameter(BinaryOpICStub::kRight);
904 905
905 Handle<Type> left_type = state.GetLeftType(isolate()); 906 Handle<Type> left_type = state.GetLeftType(isolate());
906 Handle<Type> right_type = state.GetRightType(isolate()); 907 Handle<Type> right_type = state.GetRightType(isolate());
907 Handle<Type> result_type = state.GetResultType(isolate()); 908 Handle<Type> result_type = state.GetResultType(isolate());
908 909
909 ASSERT(!left_type->Is(Type::None()) && !right_type->Is(Type::None()) && 910 ASSERT(!left_type->Is(Type::None()) && !right_type->Is(Type::None()) &&
910 (state.HasSideEffects() || !result_type->Is(Type::None()))); 911 (state.HasSideEffects() || !result_type->Is(Type::None())));
911 912
912 HValue* result = NULL; 913 HValue* result = NULL;
914 HAllocationMode allocation_mode(NOT_TENURED);
913 if (state.op() == Token::ADD && 915 if (state.op() == Token::ADD &&
914 (left_type->Maybe(Type::String()) || right_type->Maybe(Type::String())) && 916 (left_type->Maybe(Type::String()) || right_type->Maybe(Type::String())) &&
915 !left_type->Is(Type::String()) && !right_type->Is(Type::String())) { 917 !left_type->Is(Type::String()) && !right_type->Is(Type::String())) {
916 // For the generic add stub a fast case for string addition is performance 918 // For the generic add stub a fast case for string addition is performance
917 // critical. 919 // critical.
918 if (left_type->Maybe(Type::String())) { 920 if (left_type->Maybe(Type::String())) {
919 IfBuilder if_leftisstring(this); 921 IfBuilder if_leftisstring(this);
920 if_leftisstring.If<HIsStringAndBranch>(left); 922 if_leftisstring.If<HIsStringAndBranch>(left);
921 if_leftisstring.Then(); 923 if_leftisstring.Then();
922 { 924 {
923 Push(BuildBinaryOperation( 925 Push(BuildBinaryOperation(
924 state.op(), left, right, 926 state.op(), left, right,
925 handle(Type::String(), isolate()), right_type, 927 handle(Type::String(), isolate()), right_type,
926 result_type, state.fixed_right_arg())); 928 result_type, state.fixed_right_arg(),
929 allocation_mode));
927 } 930 }
928 if_leftisstring.Else(); 931 if_leftisstring.Else();
929 { 932 {
930 Push(BuildBinaryOperation( 933 Push(BuildBinaryOperation(
931 state.op(), left, right, 934 state.op(), left, right,
932 left_type, right_type, result_type, 935 left_type, right_type, result_type,
933 state.fixed_right_arg())); 936 state.fixed_right_arg(), allocation_mode));
934 } 937 }
935 if_leftisstring.End(); 938 if_leftisstring.End();
936 result = Pop(); 939 result = Pop();
937 } else { 940 } else {
938 IfBuilder if_rightisstring(this); 941 IfBuilder if_rightisstring(this);
939 if_rightisstring.If<HIsStringAndBranch>(right); 942 if_rightisstring.If<HIsStringAndBranch>(right);
940 if_rightisstring.Then(); 943 if_rightisstring.Then();
941 { 944 {
942 Push(BuildBinaryOperation( 945 Push(BuildBinaryOperation(
943 state.op(), left, right, 946 state.op(), left, right,
944 left_type, handle(Type::String(), isolate()), 947 left_type, handle(Type::String(), isolate()),
945 result_type, state.fixed_right_arg())); 948 result_type, state.fixed_right_arg(),
949 allocation_mode));
946 } 950 }
947 if_rightisstring.Else(); 951 if_rightisstring.Else();
948 { 952 {
949 Push(BuildBinaryOperation( 953 Push(BuildBinaryOperation(
950 state.op(), left, right, 954 state.op(), left, right,
951 left_type, right_type, result_type, 955 left_type, right_type, result_type,
952 state.fixed_right_arg())); 956 state.fixed_right_arg(), allocation_mode));
953 } 957 }
954 if_rightisstring.End(); 958 if_rightisstring.End();
955 result = Pop(); 959 result = Pop();
956 } 960 }
957 } else { 961 } else {
958 result = BuildBinaryOperation( 962 result = BuildBinaryOperation(
959 state.op(), left, right, 963 state.op(), left, right,
960 left_type, right_type, result_type, 964 left_type, right_type, result_type,
961 state.fixed_right_arg()); 965 state.fixed_right_arg(), allocation_mode);
962 } 966 }
963 967
964 // If we encounter a generic argument, the number conversion is 968 // If we encounter a generic argument, the number conversion is
965 // observable, thus we cannot afford to bail out after the fact. 969 // observable, thus we cannot afford to bail out after the fact.
966 if (!state.HasSideEffects()) { 970 if (!state.HasSideEffects()) {
967 if (result_type->Is(Type::Smi())) { 971 if (result_type->Is(Type::Smi())) {
968 if (state.op() == Token::SHR) { 972 if (state.op() == Token::SHR) {
969 // TODO(olivf) Replace this by a SmiTagU Instruction. 973 // TODO(olivf) Replace this by a SmiTagU Instruction.
970 // 0x40000000: this number would convert to negative when interpreting 974 // 0x40000000: this number would convert to negative when interpreting
971 // the register as signed value; 975 // the register as signed value;
(...skipping 27 matching lines...) Expand all
999 return result; 1003 return result;
1000 } 1004 }
1001 1005
1002 1006
1003 Handle<Code> BinaryOpICStub::GenerateCode(Isolate* isolate) { 1007 Handle<Code> BinaryOpICStub::GenerateCode(Isolate* isolate) {
1004 return DoGenerateCode(isolate, this); 1008 return DoGenerateCode(isolate, this);
1005 } 1009 }
1006 1010
1007 1011
1008 template <> 1012 template <>
1013 HValue* CodeStubGraphBuilder<BinaryOpWithAllocationSiteStub>::BuildCodeStub() {
1014 BinaryOpIC::State state = casted_stub()->state();
1015
1016 HValue* allocation_site = GetParameter(
1017 BinaryOpWithAllocationSiteStub::kAllocationSite);
1018 HValue* left = GetParameter(BinaryOpWithAllocationSiteStub::kLeft);
1019 HValue* right = GetParameter(BinaryOpWithAllocationSiteStub::kRight);
1020
1021 Handle<Type> left_type = state.GetLeftType(isolate());
1022 Handle<Type> right_type = state.GetRightType(isolate());
1023 Handle<Type> result_type = state.GetResultType(isolate());
1024 HAllocationMode allocation_mode(allocation_site);
1025
1026 return BuildBinaryOperation(state.op(), left, right,
1027 left_type, right_type, result_type,
1028 state.fixed_right_arg(), allocation_mode);
1029 }
1030
1031
1032 Handle<Code> BinaryOpWithAllocationSiteStub::GenerateCode(Isolate* isolate) {
1033 return DoGenerateCode(isolate, this);
1034 }
1035
1036
1037 template <>
1009 HValue* CodeStubGraphBuilder<NewStringAddStub>::BuildCodeInitializedStub() { 1038 HValue* CodeStubGraphBuilder<NewStringAddStub>::BuildCodeInitializedStub() {
1010 NewStringAddStub* stub = casted_stub(); 1039 NewStringAddStub* stub = casted_stub();
1011 StringAddFlags flags = stub->flags(); 1040 StringAddFlags flags = stub->flags();
1012 PretenureFlag pretenure_flag = stub->pretenure_flag(); 1041 PretenureFlag pretenure_flag = stub->pretenure_flag();
1013 1042
1014 HValue* left = GetParameter(NewStringAddStub::kLeft); 1043 HValue* left = GetParameter(NewStringAddStub::kLeft);
1015 HValue* right = GetParameter(NewStringAddStub::kRight); 1044 HValue* right = GetParameter(NewStringAddStub::kRight);
1016 1045
1017 // Make sure that both arguments are strings if not known in advance. 1046 // Make sure that both arguments are strings if not known in advance.
1018 if ((flags & STRING_ADD_CHECK_LEFT) == STRING_ADD_CHECK_LEFT) { 1047 if ((flags & STRING_ADD_CHECK_LEFT) == STRING_ADD_CHECK_LEFT) {
1019 left = BuildCheckString(left); 1048 left = BuildCheckString(left);
1020 } 1049 }
1021 if ((flags & STRING_ADD_CHECK_RIGHT) == STRING_ADD_CHECK_RIGHT) { 1050 if ((flags & STRING_ADD_CHECK_RIGHT) == STRING_ADD_CHECK_RIGHT) {
1022 right = BuildCheckString(right); 1051 right = BuildCheckString(right);
1023 } 1052 }
1024 1053
1025 return BuildStringAdd(left, right, pretenure_flag); 1054 return BuildStringAdd(left, right, HAllocationMode(pretenure_flag));
1026 } 1055 }
1027 1056
1028 1057
1029 Handle<Code> NewStringAddStub::GenerateCode(Isolate* isolate) { 1058 Handle<Code> NewStringAddStub::GenerateCode(Isolate* isolate) {
1030 return DoGenerateCode(isolate, this); 1059 return DoGenerateCode(isolate, this);
1031 } 1060 }
1032 1061
1033 1062
1034 template <> 1063 template <>
1035 HValue* CodeStubGraphBuilder<ToBooleanStub>::BuildCodeInitializedStub() { 1064 HValue* CodeStubGraphBuilder<ToBooleanStub>::BuildCodeInitializedStub() {
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
1186 } 1215 }
1187 is_optimized.Else(); 1216 is_optimized.Else();
1188 { 1217 {
1189 AddIncrementCounter(counters->fast_new_closure_try_optimized()); 1218 AddIncrementCounter(counters->fast_new_closure_try_optimized());
1190 // optimized_map points to fixed array of 3-element entries 1219 // optimized_map points to fixed array of 3-element entries
1191 // (native context, optimized code, literals). 1220 // (native context, optimized code, literals).
1192 // Map must never be empty, so check the first elements. 1221 // Map must never be empty, so check the first elements.
1193 Label install_optimized; 1222 Label install_optimized;
1194 HValue* first_context_slot = Add<HLoadNamedField>(optimized_map, 1223 HValue* first_context_slot = Add<HLoadNamedField>(optimized_map,
1195 HObjectAccess::ForFirstContextSlot()); 1224 HObjectAccess::ForFirstContextSlot());
1225 HValue* first_osr_ast_slot = Add<HLoadNamedField>(optimized_map,
1226 HObjectAccess::ForFirstOsrAstIdSlot());
1227 HValue* osr_ast_id_none = Add<HConstant>(BailoutId::None().ToInt());
1196 IfBuilder already_in(this); 1228 IfBuilder already_in(this);
1197 already_in.If<HCompareObjectEqAndBranch>(native_context, 1229 already_in.If<HCompareObjectEqAndBranch>(native_context,
1198 first_context_slot); 1230 first_context_slot);
1231 already_in.AndIf<HCompareObjectEqAndBranch>(first_osr_ast_slot,
1232 osr_ast_id_none);
1199 already_in.Then(); 1233 already_in.Then();
1200 { 1234 {
1201 HValue* code_object = Add<HLoadNamedField>(optimized_map, 1235 HValue* code_object = Add<HLoadNamedField>(optimized_map,
1202 HObjectAccess::ForFirstCodeSlot()); 1236 HObjectAccess::ForFirstCodeSlot());
1203 BuildInstallOptimizedCode(js_function, native_context, code_object); 1237 BuildInstallOptimizedCode(js_function, native_context, code_object);
1204 } 1238 }
1205 already_in.Else(); 1239 already_in.Else();
1206 { 1240 {
1207 HValue* shared_function_entry_length = 1241 HValue* shared_function_entry_length =
1208 Add<HConstant>(SharedFunctionInfo::kEntryLength); 1242 Add<HConstant>(SharedFunctionInfo::kEntryLength);
1209 LoopBuilder loop_builder(this, 1243 LoopBuilder loop_builder(this,
1210 context(), 1244 context(),
1211 LoopBuilder::kPostDecrement, 1245 LoopBuilder::kPostDecrement,
1212 shared_function_entry_length); 1246 shared_function_entry_length);
1213 HValue* array_length = Add<HLoadNamedField>(optimized_map, 1247 HValue* array_length = Add<HLoadNamedField>(optimized_map,
1214 HObjectAccess::ForFixedArrayLength()); 1248 HObjectAccess::ForFixedArrayLength());
1215 HValue* key = loop_builder.BeginBody(array_length, 1249 HValue* slot_iterator = loop_builder.BeginBody(array_length,
1216 graph()->GetConstant0(), 1250 graph()->GetConstant0(),
1217 Token::GT); 1251 Token::GT);
1218 { 1252 {
1219 // Iterate through the rest of map backwards. 1253 // Iterate through the rest of map backwards.
1220 // Do not double check first entry. 1254 // Do not double check first entry.
1221 HValue* second_entry_index = 1255 HValue* second_entry_index =
1222 Add<HConstant>(SharedFunctionInfo::kSecondEntryIndex); 1256 Add<HConstant>(SharedFunctionInfo::kSecondEntryIndex);
1223 IfBuilder restore_check(this); 1257 IfBuilder restore_check(this);
1224 restore_check.If<HCompareNumericAndBranch>(key, second_entry_index, 1258 restore_check.If<HCompareNumericAndBranch>(
1225 Token::EQ); 1259 slot_iterator, second_entry_index, Token::EQ);
1226 restore_check.Then(); 1260 restore_check.Then();
1227 { 1261 {
1228 // Store the unoptimized code 1262 // Store the unoptimized code
1229 BuildInstallCode(js_function, shared_info); 1263 BuildInstallCode(js_function, shared_info);
1230 loop_builder.Break(); 1264 loop_builder.Break();
1231 } 1265 }
1232 restore_check.Else(); 1266 restore_check.Else();
1233 { 1267 {
1234 HValue* keyed_minus = AddUncasted<HSub>( 1268 STATIC_ASSERT(SharedFunctionInfo::kContextOffset == 0);
1235 key, shared_function_entry_length); 1269 STATIC_ASSERT(SharedFunctionInfo::kEntryLength -
1236 HInstruction* keyed_lookup = Add<HLoadKeyed>(optimized_map, 1270 SharedFunctionInfo::kOsrAstIdOffset == 1);
1237 keyed_minus, static_cast<HValue*>(NULL), FAST_ELEMENTS); 1271 HValue* native_context_slot = AddUncasted<HSub>(
1272 slot_iterator, shared_function_entry_length);
1273 HValue* osr_ast_id_slot = AddUncasted<HSub>(
1274 slot_iterator, graph()->GetConstant1());
1275 HInstruction* native_context_entry = Add<HLoadKeyed>(optimized_map,
1276 native_context_slot, static_cast<HValue*>(NULL), FAST_ELEMENTS);
1277 HInstruction* osr_ast_id_entry = Add<HLoadKeyed>(optimized_map,
1278 osr_ast_id_slot, static_cast<HValue*>(NULL), FAST_ELEMENTS);
1238 IfBuilder done_check(this); 1279 IfBuilder done_check(this);
1239 done_check.If<HCompareObjectEqAndBranch>(native_context, 1280 done_check.If<HCompareObjectEqAndBranch>(native_context,
1240 keyed_lookup); 1281 native_context_entry);
1282 done_check.AndIf<HCompareObjectEqAndBranch>(osr_ast_id_entry,
1283 osr_ast_id_none);
1241 done_check.Then(); 1284 done_check.Then();
1242 { 1285 {
1243 // Hit: fetch the optimized code. 1286 // Hit: fetch the optimized code.
1244 HValue* keyed_plus = AddUncasted<HAdd>( 1287 HValue* code_slot = AddUncasted<HAdd>(
1245 keyed_minus, graph()->GetConstant1()); 1288 native_context_slot, graph()->GetConstant1());
1246 HValue* code_object = Add<HLoadKeyed>(optimized_map, 1289 HValue* code_object = Add<HLoadKeyed>(optimized_map,
1247 keyed_plus, static_cast<HValue*>(NULL), FAST_ELEMENTS); 1290 code_slot, static_cast<HValue*>(NULL), FAST_ELEMENTS);
1248 BuildInstallOptimizedCode(js_function, native_context, code_object); 1291 BuildInstallOptimizedCode(js_function, native_context, code_object);
1249 1292
1250 // Fall out of the loop 1293 // Fall out of the loop
1251 loop_builder.Break(); 1294 loop_builder.Break();
1252 } 1295 }
1253 done_check.Else(); 1296 done_check.Else();
1254 done_check.End(); 1297 done_check.End();
1255 } 1298 }
1256 restore_check.End(); 1299 restore_check.End();
1257 } 1300 }
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
1331 return BuildUncheckedDictionaryElementLoad(receiver, key); 1374 return BuildUncheckedDictionaryElementLoad(receiver, key);
1332 } 1375 }
1333 1376
1334 1377
1335 Handle<Code> KeyedLoadDictionaryElementStub::GenerateCode(Isolate* isolate) { 1378 Handle<Code> KeyedLoadDictionaryElementStub::GenerateCode(Isolate* isolate) {
1336 return DoGenerateCode(isolate, this); 1379 return DoGenerateCode(isolate, this);
1337 } 1380 }
1338 1381
1339 1382
1340 } } // namespace v8::internal 1383 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/code-stubs.cc ('k') | src/codegen.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698