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

Side by Side Diff: src/deoptimizer.cc

Issue 196133017: Experimental parser: merge r19949 (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/parser
Patch Set: Created 6 years, 9 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/deoptimizer.h ('k') | src/disassembler.cc » ('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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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 374 matching lines...) Expand 10 before | Expand all | Expand 10 after
385 // Move the code to the _deoptimized_ code list. 385 // Move the code to the _deoptimized_ code list.
386 code->set_next_code_link(context->DeoptimizedCodeListHead()); 386 code->set_next_code_link(context->DeoptimizedCodeListHead());
387 context->SetDeoptimizedCodeListHead(code); 387 context->SetDeoptimizedCodeListHead(code);
388 } else { 388 } else {
389 // Not marked; preserve this element. 389 // Not marked; preserve this element.
390 prev = code; 390 prev = code;
391 } 391 }
392 element = next; 392 element = next;
393 } 393 }
394 394
395 #ifdef DEBUG
396 // Make sure all activations of optimized code can deopt at their current PC.
397 for (StackFrameIterator it(isolate, isolate->thread_local_top());
398 !it.done(); it.Advance()) {
399 StackFrame::Type type = it.frame()->type();
400 if (type == StackFrame::OPTIMIZED) {
401 Code* code = it.frame()->LookupCode();
402 if (FLAG_trace_deopt) {
403 JSFunction* function =
404 static_cast<OptimizedFrame*>(it.frame())->function();
405 CodeTracer::Scope scope(isolate->GetCodeTracer());
406 PrintF(scope.file(), "[deoptimizer patches for lazy deopt: ");
407 function->PrintName(scope.file());
408 PrintF(scope.file(),
409 " / %" V8PRIxPTR "]\n", reinterpret_cast<intptr_t>(function));
410 }
411 SafepointEntry safepoint = code->GetSafepointEntry(it.frame()->pc());
412 int deopt_index = safepoint.deoptimization_index();
413 CHECK(deopt_index != Safepoint::kNoDeoptimizationIndex);
414 }
415 }
416 #endif
417
395 // TODO(titzer): we need a handle scope only because of the macro assembler, 418 // TODO(titzer): we need a handle scope only because of the macro assembler,
396 // which is only used in EnsureCodeForDeoptimizationEntry. 419 // which is only used in EnsureCodeForDeoptimizationEntry.
397 HandleScope scope(isolate); 420 HandleScope scope(isolate);
421
398 // Now patch all the codes for deoptimization. 422 // Now patch all the codes for deoptimization.
399 for (int i = 0; i < codes.length(); i++) { 423 for (int i = 0; i < codes.length(); i++) {
400 // It is finally time to die, code object. 424 // It is finally time to die, code object.
401 // Do platform-specific patching to force any activations to lazy deopt. 425 // Do platform-specific patching to force any activations to lazy deopt.
402 PatchCodeForDeoptimization(isolate, codes[i]); 426 PatchCodeForDeoptimization(isolate, codes[i]);
403 427
404 // We might be in the middle of incremental marking with compaction. 428 // We might be in the middle of incremental marking with compaction.
405 // Tell collector to treat this code object in a special way and 429 // Tell collector to treat this code object in a special way and
406 // ignore all slots that might have been recorded on it. 430 // ignore all slots that might have been recorded on it.
407 isolate->heap()->mark_compact_collector()->InvalidateCode(codes[i]); 431 isolate->heap()->mark_compact_collector()->InvalidateCode(codes[i]);
(...skipping 553 matching lines...) Expand 10 before | Expand all | Expand 10 after
961 PrintF(trace_scope_->file(), 985 PrintF(trace_scope_->file(),
962 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" 986 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
963 V8PRIxPTR " ; caller's fp\n", 987 V8PRIxPTR " ; caller's fp\n",
964 fp_value, output_offset, value); 988 fp_value, output_offset, value);
965 } 989 }
966 ASSERT(!is_bottommost || !has_alignment_padding_ || 990 ASSERT(!is_bottommost || !has_alignment_padding_ ||
967 (fp_value & kPointerSize) != 0); 991 (fp_value & kPointerSize) != 0);
968 992
969 if (FLAG_enable_ool_constant_pool) { 993 if (FLAG_enable_ool_constant_pool) {
970 // For the bottommost output frame the constant pool pointer can be gotten 994 // For the bottommost output frame the constant pool pointer can be gotten
971 // from the input frame. For subsequent output frames, it can be gotten from 995 // from the input frame. For subsequent output frames, it can be read from
972 // the function's code. 996 // the previous frame.
973 Register constant_pool_reg =
974 JavaScriptFrame::constant_pool_pointer_register();
975 output_offset -= kPointerSize; 997 output_offset -= kPointerSize;
976 input_offset -= kPointerSize; 998 input_offset -= kPointerSize;
977 if (is_bottommost) { 999 if (is_bottommost) {
978 value = input_->GetFrameSlot(input_offset); 1000 value = input_->GetFrameSlot(input_offset);
979 } else { 1001 } else {
980 value = reinterpret_cast<intptr_t>( 1002 value = output_[frame_index - 1]->GetConstantPool();
981 function->shared()->code()->constant_pool());
982 } 1003 }
983 output_frame->SetFrameSlot(output_offset, value); 1004 output_frame->SetCallerConstantPool(output_offset, value);
984 output_frame->SetConstantPool(value);
985 if (is_topmost) output_frame->SetRegister(constant_pool_reg.code(), value);
986 if (trace_scope_) { 1005 if (trace_scope_) {
987 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" 1006 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
988 V8PRIxPTR "; constant_pool\n", 1007 V8PRIxPTR "; caller's constant_pool\n",
989 top_address + output_offset, output_offset, value); 1008 top_address + output_offset, output_offset, value);
990 } 1009 }
991 } 1010 }
992 1011
993 // For the bottommost output frame the context can be gotten from the input 1012 // For the bottommost output frame the context can be gotten from the input
994 // frame. For all subsequent output frames it can be gotten from the function 1013 // frame. For all subsequent output frames it can be gotten from the function
995 // so long as we don't inline functions that need local contexts. 1014 // so long as we don't inline functions that need local contexts.
996 Register context_reg = JavaScriptFrame::context_register(); 1015 Register context_reg = JavaScriptFrame::context_register();
997 output_offset -= kPointerSize; 1016 output_offset -= kPointerSize;
998 input_offset -= kPointerSize; 1017 input_offset -= kPointerSize;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1036 // Compute this frame's PC, state, and continuation. 1055 // Compute this frame's PC, state, and continuation.
1037 Code* non_optimized_code = function->shared()->code(); 1056 Code* non_optimized_code = function->shared()->code();
1038 FixedArray* raw_data = non_optimized_code->deoptimization_data(); 1057 FixedArray* raw_data = non_optimized_code->deoptimization_data();
1039 DeoptimizationOutputData* data = DeoptimizationOutputData::cast(raw_data); 1058 DeoptimizationOutputData* data = DeoptimizationOutputData::cast(raw_data);
1040 Address start = non_optimized_code->instruction_start(); 1059 Address start = non_optimized_code->instruction_start();
1041 unsigned pc_and_state = GetOutputInfo(data, node_id, function->shared()); 1060 unsigned pc_and_state = GetOutputInfo(data, node_id, function->shared());
1042 unsigned pc_offset = FullCodeGenerator::PcField::decode(pc_and_state); 1061 unsigned pc_offset = FullCodeGenerator::PcField::decode(pc_and_state);
1043 intptr_t pc_value = reinterpret_cast<intptr_t>(start + pc_offset); 1062 intptr_t pc_value = reinterpret_cast<intptr_t>(start + pc_offset);
1044 output_frame->SetPc(pc_value); 1063 output_frame->SetPc(pc_value);
1045 1064
1065 // Update constant pool.
1066 if (FLAG_enable_ool_constant_pool) {
1067 intptr_t constant_pool_value =
1068 reinterpret_cast<intptr_t>(non_optimized_code->constant_pool());
1069 output_frame->SetConstantPool(constant_pool_value);
1070 if (is_topmost) {
1071 Register constant_pool_reg =
1072 JavaScriptFrame::constant_pool_pointer_register();
1073 output_frame->SetRegister(constant_pool_reg.code(), constant_pool_value);
1074 }
1075 }
1076
1046 FullCodeGenerator::State state = 1077 FullCodeGenerator::State state =
1047 FullCodeGenerator::StateField::decode(pc_and_state); 1078 FullCodeGenerator::StateField::decode(pc_and_state);
1048 output_frame->SetState(Smi::FromInt(state)); 1079 output_frame->SetState(Smi::FromInt(state));
1049 1080
1050 // Set the continuation for the topmost frame. 1081 // Set the continuation for the topmost frame.
1051 if (is_topmost && bailout_type_ != DEBUGGER) { 1082 if (is_topmost && bailout_type_ != DEBUGGER) {
1052 Builtins* builtins = isolate_->builtins(); 1083 Builtins* builtins = isolate_->builtins();
1053 Code* continuation = builtins->builtin(Builtins::kNotifyDeoptimized); 1084 Code* continuation = builtins->builtin(Builtins::kNotifyDeoptimized);
1054 if (bailout_type_ == LAZY) { 1085 if (bailout_type_ == LAZY) {
1055 continuation = builtins->builtin(Builtins::kNotifyLazyDeoptimized); 1086 continuation = builtins->builtin(Builtins::kNotifyLazyDeoptimized);
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
1119 intptr_t fp_value = top_address + output_offset; 1150 intptr_t fp_value = top_address + output_offset;
1120 output_frame->SetFp(fp_value); 1151 output_frame->SetFp(fp_value);
1121 if (trace_scope_ != NULL) { 1152 if (trace_scope_ != NULL) {
1122 PrintF(trace_scope_->file(), 1153 PrintF(trace_scope_->file(),
1123 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" 1154 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1124 V8PRIxPTR " ; caller's fp\n", 1155 V8PRIxPTR " ; caller's fp\n",
1125 fp_value, output_offset, value); 1156 fp_value, output_offset, value);
1126 } 1157 }
1127 1158
1128 if (FLAG_enable_ool_constant_pool) { 1159 if (FLAG_enable_ool_constant_pool) {
1129 // A marker value is used in place of the constant pool. 1160 // Read the caller's constant pool from the previous frame.
1130 output_offset -= kPointerSize; 1161 output_offset -= kPointerSize;
1131 intptr_t constant_pool = reinterpret_cast<intptr_t>( 1162 value = output_[frame_index - 1]->GetConstantPool();
1132 Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); 1163 output_frame->SetCallerConstantPool(output_offset, value);
1133 output_frame->SetFrameSlot(output_offset, constant_pool);
1134 if (trace_scope_) { 1164 if (trace_scope_) {
1135 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" 1165 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1136 V8PRIxPTR " ; constant_pool (adaptor sentinel)\n", 1166 V8PRIxPTR "; caller's constant_pool\n",
1137 top_address + output_offset, output_offset, constant_pool); 1167 top_address + output_offset, output_offset, value);
1138 } 1168 }
1139 } 1169 }
1140 1170
1141 // A marker value is used in place of the context. 1171 // A marker value is used in place of the context.
1142 output_offset -= kPointerSize; 1172 output_offset -= kPointerSize;
1143 intptr_t context = reinterpret_cast<intptr_t>( 1173 intptr_t context = reinterpret_cast<intptr_t>(
1144 Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); 1174 Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
1145 output_frame->SetFrameSlot(output_offset, context); 1175 output_frame->SetFrameSlot(output_offset, context);
1146 if (trace_scope_ != NULL) { 1176 if (trace_scope_ != NULL) {
1147 PrintF(trace_scope_->file(), 1177 PrintF(trace_scope_->file(),
(...skipping 26 matching lines...) Expand all
1174 1204
1175 ASSERT(0 == output_offset); 1205 ASSERT(0 == output_offset);
1176 1206
1177 Builtins* builtins = isolate_->builtins(); 1207 Builtins* builtins = isolate_->builtins();
1178 Code* adaptor_trampoline = 1208 Code* adaptor_trampoline =
1179 builtins->builtin(Builtins::kArgumentsAdaptorTrampoline); 1209 builtins->builtin(Builtins::kArgumentsAdaptorTrampoline);
1180 intptr_t pc_value = reinterpret_cast<intptr_t>( 1210 intptr_t pc_value = reinterpret_cast<intptr_t>(
1181 adaptor_trampoline->instruction_start() + 1211 adaptor_trampoline->instruction_start() +
1182 isolate_->heap()->arguments_adaptor_deopt_pc_offset()->value()); 1212 isolate_->heap()->arguments_adaptor_deopt_pc_offset()->value());
1183 output_frame->SetPc(pc_value); 1213 output_frame->SetPc(pc_value);
1214 if (FLAG_enable_ool_constant_pool) {
1215 intptr_t constant_pool_value =
1216 reinterpret_cast<intptr_t>(adaptor_trampoline->constant_pool());
1217 output_frame->SetConstantPool(constant_pool_value);
1218 }
1184 } 1219 }
1185 1220
1186 1221
1187 void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator, 1222 void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator,
1188 int frame_index) { 1223 int frame_index) {
1189 Builtins* builtins = isolate_->builtins(); 1224 Builtins* builtins = isolate_->builtins();
1190 Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric); 1225 Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric);
1191 JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next())); 1226 JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next()));
1192 unsigned height = iterator->Next(); 1227 unsigned height = iterator->Next();
1193 unsigned height_in_bytes = height * kPointerSize; 1228 unsigned height_in_bytes = height * kPointerSize;
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1249 intptr_t fp_value = top_address + output_offset; 1284 intptr_t fp_value = top_address + output_offset;
1250 output_frame->SetFp(fp_value); 1285 output_frame->SetFp(fp_value);
1251 if (trace_scope_ != NULL) { 1286 if (trace_scope_ != NULL) {
1252 PrintF(trace_scope_->file(), 1287 PrintF(trace_scope_->file(),
1253 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" 1288 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1254 V8PRIxPTR " ; caller's fp\n", 1289 V8PRIxPTR " ; caller's fp\n",
1255 fp_value, output_offset, value); 1290 fp_value, output_offset, value);
1256 } 1291 }
1257 1292
1258 if (FLAG_enable_ool_constant_pool) { 1293 if (FLAG_enable_ool_constant_pool) {
1259 // The constant pool pointer can be gotten from the previous frame. 1294 // Read the caller's constant pool from the previous frame.
1260 output_offset -= kPointerSize; 1295 output_offset -= kPointerSize;
1261 value = output_[frame_index - 1]->GetConstantPool(); 1296 value = output_[frame_index - 1]->GetConstantPool();
1262 output_frame->SetFrameSlot(output_offset, value); 1297 output_frame->SetCallerConstantPool(output_offset, value);
1263 if (trace_scope_) { 1298 if (trace_scope_) {
1264 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" 1299 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1265 V8PRIxPTR " ; constant pool\n", 1300 V8PRIxPTR " ; caller's constant pool\n",
1266 top_address + output_offset, output_offset, value); 1301 top_address + output_offset, output_offset, value);
1267 } 1302 }
1268 } 1303 }
1269 1304
1270 // The context can be gotten from the previous frame. 1305 // The context can be gotten from the previous frame.
1271 output_offset -= kPointerSize; 1306 output_offset -= kPointerSize;
1272 value = output_[frame_index - 1]->GetContext(); 1307 value = output_[frame_index - 1]->GetContext();
1273 output_frame->SetFrameSlot(output_offset, value); 1308 output_frame->SetFrameSlot(output_offset, value);
1274 if (trace_scope_ != NULL) { 1309 if (trace_scope_ != NULL) {
1275 PrintF(trace_scope_->file(), 1310 PrintF(trace_scope_->file(),
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1336 V8PRIxPTR " ; allocated receiver\n", 1371 V8PRIxPTR " ; allocated receiver\n",
1337 top_address + output_offset, output_offset, value); 1372 top_address + output_offset, output_offset, value);
1338 } 1373 }
1339 1374
1340 ASSERT(0 == output_offset); 1375 ASSERT(0 == output_offset);
1341 1376
1342 intptr_t pc = reinterpret_cast<intptr_t>( 1377 intptr_t pc = reinterpret_cast<intptr_t>(
1343 construct_stub->instruction_start() + 1378 construct_stub->instruction_start() +
1344 isolate_->heap()->construct_stub_deopt_pc_offset()->value()); 1379 isolate_->heap()->construct_stub_deopt_pc_offset()->value());
1345 output_frame->SetPc(pc); 1380 output_frame->SetPc(pc);
1381 if (FLAG_enable_ool_constant_pool) {
1382 intptr_t constant_pool_value =
1383 reinterpret_cast<intptr_t>(construct_stub->constant_pool());
1384 output_frame->SetConstantPool(constant_pool_value);
1385 }
1346 } 1386 }
1347 1387
1348 1388
1349 void Deoptimizer::DoComputeAccessorStubFrame(TranslationIterator* iterator, 1389 void Deoptimizer::DoComputeAccessorStubFrame(TranslationIterator* iterator,
1350 int frame_index, 1390 int frame_index,
1351 bool is_setter_stub_frame) { 1391 bool is_setter_stub_frame) {
1352 JSFunction* accessor = JSFunction::cast(ComputeLiteral(iterator->Next())); 1392 JSFunction* accessor = JSFunction::cast(ComputeLiteral(iterator->Next()));
1353 // The receiver (and the implicit return value, if any) are expected in 1393 // The receiver (and the implicit return value, if any) are expected in
1354 // registers by the LoadIC/StoreIC, so they don't belong to the output stack 1394 // registers by the LoadIC/StoreIC, so they don't belong to the output stack
1355 // frame. This means that we have to use a height of 0. 1395 // frame. This means that we have to use a height of 0.
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1407 intptr_t fp_value = top_address + output_offset; 1447 intptr_t fp_value = top_address + output_offset;
1408 output_frame->SetFp(fp_value); 1448 output_frame->SetFp(fp_value);
1409 if (trace_scope_ != NULL) { 1449 if (trace_scope_ != NULL) {
1410 PrintF(trace_scope_->file(), 1450 PrintF(trace_scope_->file(),
1411 " 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR 1451 " 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR
1412 " ; caller's fp\n", 1452 " ; caller's fp\n",
1413 fp_value, output_offset, value); 1453 fp_value, output_offset, value);
1414 } 1454 }
1415 1455
1416 if (FLAG_enable_ool_constant_pool) { 1456 if (FLAG_enable_ool_constant_pool) {
1417 // The constant pool pointer can be gotten from the previous frame. 1457 // Read the caller's constant pool from the previous frame.
1418 output_offset -= kPointerSize; 1458 output_offset -= kPointerSize;
1419 value = output_[frame_index - 1]->GetConstantPool(); 1459 value = output_[frame_index - 1]->GetConstantPool();
1420 output_frame->SetFrameSlot(output_offset, value); 1460 output_frame->SetCallerConstantPool(output_offset, value);
1421 if (trace_scope_) { 1461 if (trace_scope_) {
1422 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" 1462 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1423 V8PRIxPTR " ; constant pool\n", 1463 V8PRIxPTR " ; caller's constant pool\n",
1424 top_address + output_offset, output_offset, value); 1464 top_address + output_offset, output_offset, value);
1425 } 1465 }
1426 } 1466 }
1427 1467
1428 // The context can be gotten from the previous frame. 1468 // The context can be gotten from the previous frame.
1429 output_offset -= kPointerSize; 1469 output_offset -= kPointerSize;
1430 value = output_[frame_index - 1]->GetContext(); 1470 value = output_[frame_index - 1]->GetContext();
1431 output_frame->SetFrameSlot(output_offset, value); 1471 output_frame->SetFrameSlot(output_offset, value);
1432 if (trace_scope_ != NULL) { 1472 if (trace_scope_ != NULL) {
1433 PrintF(trace_scope_->file(), 1473 PrintF(trace_scope_->file(),
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1475 } 1515 }
1476 1516
1477 ASSERT(0 == output_offset); 1517 ASSERT(0 == output_offset);
1478 1518
1479 Smi* offset = is_setter_stub_frame ? 1519 Smi* offset = is_setter_stub_frame ?
1480 isolate_->heap()->setter_stub_deopt_pc_offset() : 1520 isolate_->heap()->setter_stub_deopt_pc_offset() :
1481 isolate_->heap()->getter_stub_deopt_pc_offset(); 1521 isolate_->heap()->getter_stub_deopt_pc_offset();
1482 intptr_t pc = reinterpret_cast<intptr_t>( 1522 intptr_t pc = reinterpret_cast<intptr_t>(
1483 accessor_stub->instruction_start() + offset->value()); 1523 accessor_stub->instruction_start() + offset->value());
1484 output_frame->SetPc(pc); 1524 output_frame->SetPc(pc);
1525 if (FLAG_enable_ool_constant_pool) {
1526 intptr_t constant_pool_value =
1527 reinterpret_cast<intptr_t>(accessor_stub->constant_pool());
1528 output_frame->SetConstantPool(constant_pool_value);
1529 }
1485 } 1530 }
1486 1531
1487 1532
1488 void Deoptimizer::DoComputeCompiledStubFrame(TranslationIterator* iterator, 1533 void Deoptimizer::DoComputeCompiledStubFrame(TranslationIterator* iterator,
1489 int frame_index) { 1534 int frame_index) {
1490 // 1535 //
1491 // FROM TO 1536 // FROM TO
1492 // | .... | | .... | 1537 // | .... | | .... |
1493 // +-------------------------+ +-------------------------+ 1538 // +-------------------------+ +-------------------------+
1494 // | JSFunction continuation | | JSFunction continuation | 1539 // | JSFunction continuation | | JSFunction continuation |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
1578 output_frame->SetRegister(fp_reg.code(), frame_ptr); 1623 output_frame->SetRegister(fp_reg.code(), frame_ptr);
1579 output_frame->SetFp(frame_ptr); 1624 output_frame->SetFp(frame_ptr);
1580 if (trace_scope_ != NULL) { 1625 if (trace_scope_ != NULL) {
1581 PrintF(trace_scope_->file(), 1626 PrintF(trace_scope_->file(),
1582 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" 1627 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1583 V8PRIxPTR " ; caller's fp\n", 1628 V8PRIxPTR " ; caller's fp\n",
1584 top_address + output_frame_offset, output_frame_offset, value); 1629 top_address + output_frame_offset, output_frame_offset, value);
1585 } 1630 }
1586 1631
1587 if (FLAG_enable_ool_constant_pool) { 1632 if (FLAG_enable_ool_constant_pool) {
1588 // The constant pool pointer can be gotten from the input frame. 1633 // Read the caller's constant pool from the input frame.
1589 Register constant_pool_pointer_register =
1590 StubFailureTrampolineFrame::constant_pool_pointer_register();
1591 input_frame_offset -= kPointerSize; 1634 input_frame_offset -= kPointerSize;
1592 value = input_->GetFrameSlot(input_frame_offset); 1635 value = input_->GetFrameSlot(input_frame_offset);
1593 output_frame->SetRegister(constant_pool_pointer_register.code(), value);
1594 output_frame_offset -= kPointerSize; 1636 output_frame_offset -= kPointerSize;
1595 output_frame->SetFrameSlot(output_frame_offset, value); 1637 output_frame->SetCallerConstantPool(output_frame_offset, value);
1596 if (trace_scope_) { 1638 if (trace_scope_) {
1597 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" 1639 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1598 V8PRIxPTR " ; constant_pool_pointer\n", 1640 V8PRIxPTR " ; caller's constant_pool\n",
1599 top_address + output_frame_offset, output_frame_offset, value); 1641 top_address + output_frame_offset, output_frame_offset, value);
1600 } 1642 }
1601 } 1643 }
1602 1644
1603 // The context can be gotten from the input frame. 1645 // The context can be gotten from the input frame.
1604 Register context_reg = StubFailureTrampolineFrame::context_register(); 1646 Register context_reg = StubFailureTrampolineFrame::context_register();
1605 input_frame_offset -= kPointerSize; 1647 input_frame_offset -= kPointerSize;
1606 value = input_->GetFrameSlot(input_frame_offset); 1648 value = input_->GetFrameSlot(input_frame_offset);
1607 output_frame->SetRegister(context_reg.code(), value); 1649 output_frame->SetRegister(context_reg.code(), value);
1608 output_frame_offset -= kPointerSize; 1650 output_frame_offset -= kPointerSize;
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
1722 SetPlatformCompiledStubRegisters(output_frame, descriptor); 1764 SetPlatformCompiledStubRegisters(output_frame, descriptor);
1723 1765
1724 // Compute this frame's PC, state, and continuation. 1766 // Compute this frame's PC, state, and continuation.
1725 Code* trampoline = NULL; 1767 Code* trampoline = NULL;
1726 StubFunctionMode function_mode = descriptor->function_mode_; 1768 StubFunctionMode function_mode = descriptor->function_mode_;
1727 StubFailureTrampolineStub(function_mode).FindCodeInCache(&trampoline, 1769 StubFailureTrampolineStub(function_mode).FindCodeInCache(&trampoline,
1728 isolate_); 1770 isolate_);
1729 ASSERT(trampoline != NULL); 1771 ASSERT(trampoline != NULL);
1730 output_frame->SetPc(reinterpret_cast<intptr_t>( 1772 output_frame->SetPc(reinterpret_cast<intptr_t>(
1731 trampoline->instruction_start())); 1773 trampoline->instruction_start()));
1774 if (FLAG_enable_ool_constant_pool) {
1775 Register constant_pool_reg =
1776 StubFailureTrampolineFrame::constant_pool_pointer_register();
1777 intptr_t constant_pool_value =
1778 reinterpret_cast<intptr_t>(trampoline->constant_pool());
1779 output_frame->SetConstantPool(constant_pool_value);
1780 output_frame->SetRegister(constant_pool_reg.code(), constant_pool_value);
1781 }
1732 output_frame->SetState(Smi::FromInt(FullCodeGenerator::NO_REGISTERS)); 1782 output_frame->SetState(Smi::FromInt(FullCodeGenerator::NO_REGISTERS));
1733 Code* notify_failure = NotifyStubFailureBuiltin(); 1783 Code* notify_failure = NotifyStubFailureBuiltin();
1734 output_frame->SetContinuation( 1784 output_frame->SetContinuation(
1735 reinterpret_cast<intptr_t>(notify_failure->entry())); 1785 reinterpret_cast<intptr_t>(notify_failure->entry()));
1736 } 1786 }
1737 1787
1738 1788
1739 Handle<Object> Deoptimizer::MaterializeNextHeapObject() { 1789 Handle<Object> Deoptimizer::MaterializeNextHeapObject() {
1740 int object_index = materialization_object_index_++; 1790 int object_index = materialization_object_index_++;
1741 ObjectMaterializationDescriptor desc = deferred_objects_[object_index]; 1791 ObjectMaterializationDescriptor desc = deferred_objects_[object_index];
1742 const int length = desc.object_length(); 1792 const int length = desc.object_length();
1743 1793
1744 if (desc.duplicate_object() >= 0) { 1794 if (desc.duplicate_object() >= 0) {
1745 // Found a previously materialized object by de-duplication. 1795 // Found a previously materialized object by de-duplication.
1746 object_index = desc.duplicate_object(); 1796 object_index = desc.duplicate_object();
1747 materialized_objects_->Add(Handle<Object>()); 1797 materialized_objects_->Add(Handle<Object>());
1748 } else if (desc.is_arguments() && ArgumentsObjectIsAdapted(object_index)) { 1798 } else if (desc.is_arguments() && ArgumentsObjectIsAdapted(object_index)) {
1749 // Use the arguments adapter frame we just built to materialize the 1799 // Use the arguments adapter frame we just built to materialize the
1750 // arguments object. FunctionGetArguments can't throw an exception. 1800 // arguments object. FunctionGetArguments can't throw an exception.
1751 Handle<JSFunction> function = ArgumentsObjectFunction(object_index); 1801 Handle<JSFunction> function = ArgumentsObjectFunction(object_index);
1752 Handle<JSObject> arguments = Handle<JSObject>::cast( 1802 Handle<JSObject> arguments = Handle<JSObject>::cast(
1753 Accessors::FunctionGetArguments(function)); 1803 Accessors::FunctionGetArguments(function));
1754 materialized_objects_->Add(arguments); 1804 materialized_objects_->Add(arguments);
1755 materialization_value_index_ += length; 1805 // To keep consistent object counters, we still materialize the
1806 // nested values (but we throw them away).
1807 for (int i = 0; i < length; ++i) {
1808 MaterializeNextValue();
1809 }
1756 } else if (desc.is_arguments()) { 1810 } else if (desc.is_arguments()) {
1757 // Construct an arguments object and copy the parameters to a newly 1811 // Construct an arguments object and copy the parameters to a newly
1758 // allocated arguments object backing store. 1812 // allocated arguments object backing store.
1759 Handle<JSFunction> function = ArgumentsObjectFunction(object_index); 1813 Handle<JSFunction> function = ArgumentsObjectFunction(object_index);
1760 Handle<JSObject> arguments = 1814 Handle<JSObject> arguments =
1761 isolate_->factory()->NewArgumentsObject(function, length); 1815 isolate_->factory()->NewArgumentsObject(function, length);
1762 Handle<FixedArray> array = isolate_->factory()->NewFixedArray(length); 1816 Handle<FixedArray> array = isolate_->factory()->NewFixedArray(length);
1763 ASSERT(array->length() == length); 1817 ASSERT(array->length() == length);
1764 arguments->set_elements(*array); 1818 arguments->set_elements(*array);
1765 materialized_objects_->Add(arguments); 1819 materialized_objects_->Add(arguments);
(...skipping 1510 matching lines...) Expand 10 before | Expand all | Expand 10 after
3276 Handle<Map>::cast(map_object), Representation::Tagged()); 3330 Handle<Map>::cast(map_object), Representation::Tagged());
3277 current_slot_++; 3331 current_slot_++;
3278 // TODO(jarin) this should be unified with the code in 3332 // TODO(jarin) this should be unified with the code in
3279 // Deoptimizer::MaterializeNextHeapObject() 3333 // Deoptimizer::MaterializeNextHeapObject()
3280 switch (map->instance_type()) { 3334 switch (map->instance_type()) {
3281 case HEAP_NUMBER_TYPE: { 3335 case HEAP_NUMBER_TYPE: {
3282 // Reuse the HeapNumber value directly as it is already properly 3336 // Reuse the HeapNumber value directly as it is already properly
3283 // tagged and skip materializing the HeapNumber explicitly. 3337 // tagged and skip materializing the HeapNumber explicitly.
3284 Handle<Object> object = GetNext(isolate, lvl + 1); 3338 Handle<Object> object = GetNext(isolate, lvl + 1);
3285 materialized_objects_.Add(object); 3339 materialized_objects_.Add(object);
3340 // On 32-bit architectures, there is an extra slot there because
3341 // the escape analysis calculates the number of slots as
3342 // object-size/pointer-size. To account for this, we read out
3343 // any extra slots.
3344 for (int i = 0; i < length - 2; i++) {
3345 GetNext(isolate, lvl + 1);
3346 }
3286 return object; 3347 return object;
3287 } 3348 }
3288 case JS_OBJECT_TYPE: { 3349 case JS_OBJECT_TYPE: {
3289 Handle<JSObject> object = 3350 Handle<JSObject> object =
3290 isolate->factory()->NewJSObjectFromMap(map, NOT_TENURED, false); 3351 isolate->factory()->NewJSObjectFromMap(map, NOT_TENURED, false);
3291 materialized_objects_.Add(object); 3352 materialized_objects_.Add(object);
3292 Handle<Object> properties = GetNext(isolate, lvl + 1); 3353 Handle<Object> properties = GetNext(isolate, lvl + 1);
3293 Handle<Object> elements = GetNext(isolate, lvl + 1); 3354 Handle<Object> elements = GetNext(isolate, lvl + 1);
3294 object->set_properties(FixedArray::cast(*properties)); 3355 object->set_properties(FixedArray::cast(*properties));
3295 object->set_elements(FixedArrayBase::cast(*elements)); 3356 object->set_elements(FixedArrayBase::cast(*elements));
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
3330 UNREACHABLE(); 3391 UNREACHABLE();
3331 break; 3392 break;
3332 } 3393 }
3333 3394
3334 FATAL("We should never get here - unexpected deopt slot kind."); 3395 FATAL("We should never get here - unexpected deopt slot kind.");
3335 return Handle<Object>::null(); 3396 return Handle<Object>::null();
3336 } 3397 }
3337 3398
3338 3399
3339 void SlotRefValueBuilder::Finish(Isolate* isolate) { 3400 void SlotRefValueBuilder::Finish(Isolate* isolate) {
3340 // We should have processed all slot 3401 // We should have processed all the slots
3341 ASSERT(slot_refs_.length() == current_slot_); 3402 ASSERT(slot_refs_.length() == current_slot_);
3342 3403
3343 if (materialized_objects_.length() > prev_materialized_count_) { 3404 if (materialized_objects_.length() > prev_materialized_count_) {
3344 // We have materialized some new objects, so we have to store them 3405 // We have materialized some new objects, so we have to store them
3345 // to prevent duplicate materialization 3406 // to prevent duplicate materialization
3346 Handle<FixedArray> array = isolate->factory()->NewFixedArray( 3407 Handle<FixedArray> array = isolate->factory()->NewFixedArray(
3347 materialized_objects_.length()); 3408 materialized_objects_.length());
3348 for (int i = 0; i < materialized_objects_.length(); i++) { 3409 for (int i = 0; i < materialized_objects_.length(); i++) {
3349 array->set(i, *(materialized_objects_.at(i))); 3410 array->set(i, *(materialized_objects_.at(i)));
3350 } 3411 }
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
3471 3532
3472 void DeoptimizedFrameInfo::Iterate(ObjectVisitor* v) { 3533 void DeoptimizedFrameInfo::Iterate(ObjectVisitor* v) {
3473 v->VisitPointer(BitCast<Object**>(&function_)); 3534 v->VisitPointer(BitCast<Object**>(&function_));
3474 v->VisitPointers(parameters_, parameters_ + parameters_count_); 3535 v->VisitPointers(parameters_, parameters_ + parameters_count_);
3475 v->VisitPointers(expression_stack_, expression_stack_ + expression_count_); 3536 v->VisitPointers(expression_stack_, expression_stack_ + expression_count_);
3476 } 3537 }
3477 3538
3478 #endif // ENABLE_DEBUGGER_SUPPORT 3539 #endif // ENABLE_DEBUGGER_SUPPORT
3479 3540
3480 } } // namespace v8::internal 3541 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/deoptimizer.h ('k') | src/disassembler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698