OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/compiler/bytecode-graph-builder.h" | 5 #include "src/compiler/bytecode-graph-builder.h" |
6 | 6 |
7 #include "src/ast/ast.h" | 7 #include "src/ast/ast.h" |
8 #include "src/ast/scopes.h" | 8 #include "src/ast/scopes.h" |
9 #include "src/compilation-info.h" | 9 #include "src/compilation-info.h" |
10 #include "src/compiler/compiler-source-position-table.h" | 10 #include "src/compiler/compiler-source-position-table.h" |
(...skipping 1275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1286 // only an estimate and does not match {ObjectLiteral::properties_count}. | 1286 // only an estimate and does not match {ObjectLiteral::properties_count}. |
1287 int number_of_properties = constant_properties->size(); | 1287 int number_of_properties = constant_properties->size(); |
1288 Node* literal = NewNode( | 1288 Node* literal = NewNode( |
1289 javascript()->CreateLiteralObject(constant_properties, literal_flags, | 1289 javascript()->CreateLiteralObject(constant_properties, literal_flags, |
1290 literal_index, number_of_properties), | 1290 literal_index, number_of_properties), |
1291 GetFunctionClosure()); | 1291 GetFunctionClosure()); |
1292 environment()->BindRegister(bytecode_iterator().GetRegisterOperand(3), | 1292 environment()->BindRegister(bytecode_iterator().GetRegisterOperand(3), |
1293 literal, Environment::kAttachFrameState); | 1293 literal, Environment::kAttachFrameState); |
1294 } | 1294 } |
1295 | 1295 |
1296 Node* BytecodeGraphBuilder::ProcessCallArguments(const Operator* call_op, | 1296 Node* const* BytecodeGraphBuilder::GetCallArgumentsFromRegister( |
1297 Node* callee, | 1297 Node* callee, interpreter::Register receiver, size_t arity) { |
1298 interpreter::Register receiver, | |
1299 size_t arity) { | |
1300 Node** all = local_zone()->NewArray<Node*>(static_cast<int>(arity)); | 1298 Node** all = local_zone()->NewArray<Node*>(static_cast<int>(arity)); |
1301 all[0] = callee; | 1299 all[0] = callee; |
1302 all[1] = environment()->LookupRegister(receiver); | 1300 all[1] = environment()->LookupRegister(receiver); |
1303 int receiver_index = receiver.index(); | 1301 int receiver_index = receiver.index(); |
1304 for (int i = 2; i < static_cast<int>(arity); ++i) { | 1302 for (int i = 2; i < static_cast<int>(arity); ++i) { |
1305 all[i] = environment()->LookupRegister( | 1303 all[i] = environment()->LookupRegister( |
1306 interpreter::Register(receiver_index + i - 1)); | 1304 interpreter::Register(receiver_index + i - 1)); |
1307 } | 1305 } |
1308 Node* value = MakeNode(call_op, static_cast<int>(arity), all, false); | 1306 return all; |
1309 return value; | 1307 } |
| 1308 |
| 1309 Node* BytecodeGraphBuilder::ProcessCallArguments(const Operator* call_op, |
| 1310 Node* const* args, |
| 1311 size_t arg_count) { |
| 1312 return MakeNode(call_op, static_cast<int>(arg_count), args, false); |
| 1313 } |
| 1314 |
| 1315 Node* BytecodeGraphBuilder::ProcessCallArguments(const Operator* call_op, |
| 1316 Node* callee, |
| 1317 interpreter::Register receiver, |
| 1318 size_t arg_count) { |
| 1319 return ProcessCallArguments( |
| 1320 call_op, GetCallArgumentsFromRegister(callee, receiver, arg_count), |
| 1321 arg_count); |
1310 } | 1322 } |
1311 | 1323 |
1312 void BytecodeGraphBuilder::BuildCall(TailCallMode tail_call_mode, | 1324 void BytecodeGraphBuilder::BuildCall(TailCallMode tail_call_mode, |
1313 ConvertReceiverMode receiver_hint) { | 1325 ConvertReceiverMode receiver_hint, |
| 1326 Node* const* args, size_t arg_count, |
| 1327 int slot_id) { |
1314 PrepareEagerCheckpoint(); | 1328 PrepareEagerCheckpoint(); |
1315 | 1329 |
| 1330 // Slot index of 0 is used indicate no feedback slot is available. Assert |
| 1331 // the assumption that slot index 0 is never a valid feedback slot. |
| 1332 STATIC_ASSERT(FeedbackVector::kReservedIndexCount > 0); |
| 1333 VectorSlotPair feedback = CreateVectorSlotPair(slot_id); |
| 1334 |
| 1335 float const frequency = ComputeCallFrequency(slot_id); |
| 1336 const Operator* call = javascript()->Call(arg_count, frequency, feedback, |
| 1337 receiver_hint, tail_call_mode); |
| 1338 Node* value = ProcessCallArguments(call, args, arg_count); |
| 1339 environment()->BindAccumulator(value, Environment::kAttachFrameState); |
| 1340 } |
| 1341 |
| 1342 void BytecodeGraphBuilder::BuildCallVarArgs(TailCallMode tail_call_mode, |
| 1343 ConvertReceiverMode receiver_hint) { |
1316 Node* callee = | 1344 Node* callee = |
1317 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); | 1345 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); |
1318 interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1); | 1346 interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1); |
1319 size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2); | 1347 size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2); |
1320 | |
1321 // Slot index of 0 is used indicate no feedback slot is available. Assert | |
1322 // the assumption that slot index 0 is never a valid feedback slot. | |
1323 STATIC_ASSERT(FeedbackVector::kReservedIndexCount > 0); | |
1324 int const slot_id = bytecode_iterator().GetIndexOperand(3); | 1348 int const slot_id = bytecode_iterator().GetIndexOperand(3); |
1325 VectorSlotPair feedback = CreateVectorSlotPair(slot_id); | 1349 BuildCall(tail_call_mode, receiver_hint, |
1326 | 1350 GetCallArgumentsFromRegister(callee, receiver, arg_count + 1), |
1327 float const frequency = ComputeCallFrequency(slot_id); | 1351 arg_count + 1, slot_id); |
1328 const Operator* call = javascript()->Call(arg_count + 1, frequency, feedback, | |
1329 receiver_hint, tail_call_mode); | |
1330 Node* value = ProcessCallArguments(call, callee, receiver, arg_count + 1); | |
1331 environment()->BindAccumulator(value, Environment::kAttachFrameState); | |
1332 } | 1352 } |
1333 | 1353 |
1334 void BytecodeGraphBuilder::VisitCall() { | 1354 void BytecodeGraphBuilder::VisitCall() { |
1335 BuildCall(TailCallMode::kDisallow, ConvertReceiverMode::kAny); | 1355 BuildCallVarArgs(TailCallMode::kDisallow, ConvertReceiverMode::kAny); |
| 1356 } |
| 1357 |
| 1358 void BytecodeGraphBuilder::VisitCall0() { |
| 1359 Node* callee = |
| 1360 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); |
| 1361 Node* receiver = |
| 1362 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1)); |
| 1363 int const slot_id = bytecode_iterator().GetIndexOperand(2); |
| 1364 BuildCall(TailCallMode::kDisallow, ConvertReceiverMode::kAny, |
| 1365 {callee, receiver}, slot_id); |
| 1366 } |
| 1367 |
| 1368 void BytecodeGraphBuilder::VisitCall1() { |
| 1369 Node* callee = |
| 1370 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); |
| 1371 Node* receiver = |
| 1372 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1)); |
| 1373 Node* arg0 = |
| 1374 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(2)); |
| 1375 int const slot_id = bytecode_iterator().GetIndexOperand(3); |
| 1376 BuildCall(TailCallMode::kDisallow, ConvertReceiverMode::kAny, |
| 1377 {callee, receiver, arg0}, slot_id); |
| 1378 } |
| 1379 |
| 1380 void BytecodeGraphBuilder::VisitCall2() { |
| 1381 Node* callee = |
| 1382 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); |
| 1383 Node* receiver = |
| 1384 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1)); |
| 1385 Node* arg0 = |
| 1386 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(2)); |
| 1387 Node* arg1 = |
| 1388 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(3)); |
| 1389 int const slot_id = bytecode_iterator().GetIndexOperand(4); |
| 1390 BuildCall(TailCallMode::kDisallow, ConvertReceiverMode::kAny, |
| 1391 {callee, receiver, arg0, arg1}, slot_id); |
| 1392 } |
| 1393 |
| 1394 void BytecodeGraphBuilder::VisitCallProperty() { |
| 1395 BuildCallVarArgs(TailCallMode::kDisallow, |
| 1396 ConvertReceiverMode::kNotNullOrUndefined); |
| 1397 } |
| 1398 |
| 1399 void BytecodeGraphBuilder::VisitCallProperty0() { |
| 1400 Node* callee = |
| 1401 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); |
| 1402 Node* receiver = |
| 1403 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1)); |
| 1404 int const slot_id = bytecode_iterator().GetIndexOperand(2); |
| 1405 BuildCall(TailCallMode::kDisallow, ConvertReceiverMode::kNotNullOrUndefined, |
| 1406 {callee, receiver}, slot_id); |
| 1407 } |
| 1408 |
| 1409 void BytecodeGraphBuilder::VisitCallProperty1() { |
| 1410 Node* callee = |
| 1411 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); |
| 1412 Node* receiver = |
| 1413 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1)); |
| 1414 Node* arg0 = |
| 1415 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(2)); |
| 1416 int const slot_id = bytecode_iterator().GetIndexOperand(3); |
| 1417 BuildCall(TailCallMode::kDisallow, ConvertReceiverMode::kNotNullOrUndefined, |
| 1418 {callee, receiver, arg0}, slot_id); |
| 1419 } |
| 1420 |
| 1421 void BytecodeGraphBuilder::VisitCallProperty2() { |
| 1422 Node* callee = |
| 1423 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); |
| 1424 Node* receiver = |
| 1425 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1)); |
| 1426 Node* arg0 = |
| 1427 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(2)); |
| 1428 Node* arg1 = |
| 1429 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(3)); |
| 1430 int const slot_id = bytecode_iterator().GetIndexOperand(4); |
| 1431 BuildCall(TailCallMode::kDisallow, ConvertReceiverMode::kNotNullOrUndefined, |
| 1432 {callee, receiver, arg0, arg1}, slot_id); |
1336 } | 1433 } |
1337 | 1434 |
1338 void BytecodeGraphBuilder::VisitCallWithSpread() { | 1435 void BytecodeGraphBuilder::VisitCallWithSpread() { |
1339 PrepareEagerCheckpoint(); | 1436 PrepareEagerCheckpoint(); |
1340 Node* callee = | 1437 Node* callee = |
1341 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); | 1438 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); |
1342 interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1); | 1439 interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1); |
1343 size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2); | 1440 size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2); |
1344 const Operator* call = | 1441 const Operator* call = |
1345 javascript()->CallWithSpread(static_cast<int>(arg_count + 1)); | 1442 javascript()->CallWithSpread(static_cast<int>(arg_count + 1)); |
1346 | 1443 |
1347 Node* value = ProcessCallArguments(call, callee, receiver, arg_count + 1); | 1444 Node* value = ProcessCallArguments(call, callee, receiver, arg_count + 1); |
1348 environment()->BindAccumulator(value, Environment::kAttachFrameState); | 1445 environment()->BindAccumulator(value, Environment::kAttachFrameState); |
1349 } | 1446 } |
1350 | 1447 |
1351 void BytecodeGraphBuilder::VisitCallProperty() { | |
1352 BuildCall(TailCallMode::kDisallow, ConvertReceiverMode::kNotNullOrUndefined); | |
1353 } | |
1354 | |
1355 void BytecodeGraphBuilder::VisitTailCall() { | 1448 void BytecodeGraphBuilder::VisitTailCall() { |
1356 TailCallMode tail_call_mode = | 1449 TailCallMode tail_call_mode = |
1357 bytecode_array_->GetIsolate()->is_tail_call_elimination_enabled() | 1450 bytecode_array_->GetIsolate()->is_tail_call_elimination_enabled() |
1358 ? TailCallMode::kAllow | 1451 ? TailCallMode::kAllow |
1359 : TailCallMode::kDisallow; | 1452 : TailCallMode::kDisallow; |
1360 BuildCall(tail_call_mode, ConvertReceiverMode::kAny); | 1453 BuildCallVarArgs(tail_call_mode, ConvertReceiverMode::kAny); |
1361 } | 1454 } |
1362 | 1455 |
1363 void BytecodeGraphBuilder::VisitCallJSRuntime() { | 1456 void BytecodeGraphBuilder::VisitCallJSRuntime() { |
1364 PrepareEagerCheckpoint(); | 1457 PrepareEagerCheckpoint(); |
1365 Node* callee = | 1458 Node* callee = |
1366 BuildLoadNativeContextField(bytecode_iterator().GetIndexOperand(0)); | 1459 BuildLoadNativeContextField(bytecode_iterator().GetIndexOperand(0)); |
1367 interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1); | 1460 interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1); |
1368 size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2); | 1461 size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2); |
1369 | 1462 |
1370 // Create node to perform the JS runtime call. | 1463 // Create node to perform the JS runtime call. |
(...skipping 887 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2258 int next_end = table->GetRangeEnd(current_exception_handler_); | 2351 int next_end = table->GetRangeEnd(current_exception_handler_); |
2259 int next_handler = table->GetRangeHandler(current_exception_handler_); | 2352 int next_handler = table->GetRangeHandler(current_exception_handler_); |
2260 int context_register = table->GetRangeData(current_exception_handler_); | 2353 int context_register = table->GetRangeData(current_exception_handler_); |
2261 exception_handlers_.push( | 2354 exception_handlers_.push( |
2262 {next_start, next_end, next_handler, context_register}); | 2355 {next_start, next_end, next_handler, context_register}); |
2263 current_exception_handler_++; | 2356 current_exception_handler_++; |
2264 } | 2357 } |
2265 } | 2358 } |
2266 | 2359 |
2267 Node* BytecodeGraphBuilder::MakeNode(const Operator* op, int value_input_count, | 2360 Node* BytecodeGraphBuilder::MakeNode(const Operator* op, int value_input_count, |
2268 Node** value_inputs, bool incomplete) { | 2361 Node* const* value_inputs, |
| 2362 bool incomplete) { |
2269 DCHECK_EQ(op->ValueInputCount(), value_input_count); | 2363 DCHECK_EQ(op->ValueInputCount(), value_input_count); |
2270 | 2364 |
2271 bool has_context = OperatorProperties::HasContextInput(op); | 2365 bool has_context = OperatorProperties::HasContextInput(op); |
2272 bool has_frame_state = OperatorProperties::HasFrameStateInput(op); | 2366 bool has_frame_state = OperatorProperties::HasFrameStateInput(op); |
2273 bool has_control = op->ControlInputCount() == 1; | 2367 bool has_control = op->ControlInputCount() == 1; |
2274 bool has_effect = op->EffectInputCount() == 1; | 2368 bool has_effect = op->EffectInputCount() == 1; |
2275 | 2369 |
2276 DCHECK_LT(op->ControlInputCount(), 2); | 2370 DCHECK_LT(op->ControlInputCount(), 2); |
2277 DCHECK_LT(op->EffectInputCount(), 2); | 2371 DCHECK_LT(op->EffectInputCount(), 2); |
2278 | 2372 |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2430 it->source_position().ScriptOffset(), start_position_.InliningId())); | 2524 it->source_position().ScriptOffset(), start_position_.InliningId())); |
2431 it->Advance(); | 2525 it->Advance(); |
2432 } else { | 2526 } else { |
2433 DCHECK_GT(it->code_offset(), offset); | 2527 DCHECK_GT(it->code_offset(), offset); |
2434 } | 2528 } |
2435 } | 2529 } |
2436 | 2530 |
2437 } // namespace compiler | 2531 } // namespace compiler |
2438 } // namespace internal | 2532 } // namespace internal |
2439 } // namespace v8 | 2533 } // namespace v8 |
OLD | NEW |