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* const* BytecodeGraphBuilder::GetCallArgumentsFromRegister( | 1296 Node* BytecodeGraphBuilder::ProcessCallArguments(const Operator* call_op, |
1297 Node* callee, interpreter::Register receiver, size_t arity) { | 1297 Node* callee, |
| 1298 interpreter::Register receiver, |
| 1299 size_t arity) { |
1298 Node** all = local_zone()->NewArray<Node*>(static_cast<int>(arity)); | 1300 Node** all = local_zone()->NewArray<Node*>(static_cast<int>(arity)); |
1299 all[0] = callee; | 1301 all[0] = callee; |
1300 all[1] = environment()->LookupRegister(receiver); | 1302 all[1] = environment()->LookupRegister(receiver); |
1301 int receiver_index = receiver.index(); | 1303 int receiver_index = receiver.index(); |
1302 for (int i = 2; i < static_cast<int>(arity); ++i) { | 1304 for (int i = 2; i < static_cast<int>(arity); ++i) { |
1303 all[i] = environment()->LookupRegister( | 1305 all[i] = environment()->LookupRegister( |
1304 interpreter::Register(receiver_index + i - 1)); | 1306 interpreter::Register(receiver_index + i - 1)); |
1305 } | 1307 } |
1306 return all; | 1308 Node* value = MakeNode(call_op, static_cast<int>(arity), all, false); |
1307 } | 1309 return value; |
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); | |
1322 } | 1310 } |
1323 | 1311 |
1324 void BytecodeGraphBuilder::BuildCall(TailCallMode tail_call_mode, | 1312 void BytecodeGraphBuilder::BuildCall(TailCallMode tail_call_mode, |
1325 ConvertReceiverMode receiver_hint, | 1313 ConvertReceiverMode receiver_hint) { |
1326 Node* const* args, size_t arg_count, | |
1327 int slot_id) { | |
1328 PrepareEagerCheckpoint(); | 1314 PrepareEagerCheckpoint(); |
1329 | 1315 |
| 1316 Node* callee = |
| 1317 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); |
| 1318 interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1); |
| 1319 size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2); |
| 1320 |
1330 // Slot index of 0 is used indicate no feedback slot is available. Assert | 1321 // 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. | 1322 // the assumption that slot index 0 is never a valid feedback slot. |
1332 STATIC_ASSERT(FeedbackVector::kReservedIndexCount > 0); | 1323 STATIC_ASSERT(FeedbackVector::kReservedIndexCount > 0); |
| 1324 int const slot_id = bytecode_iterator().GetIndexOperand(3); |
1333 VectorSlotPair feedback = CreateVectorSlotPair(slot_id); | 1325 VectorSlotPair feedback = CreateVectorSlotPair(slot_id); |
1334 | 1326 |
1335 float const frequency = ComputeCallFrequency(slot_id); | 1327 float const frequency = ComputeCallFrequency(slot_id); |
1336 const Operator* call = javascript()->Call(arg_count, frequency, feedback, | 1328 const Operator* call = javascript()->Call(arg_count + 1, frequency, feedback, |
1337 receiver_hint, tail_call_mode); | 1329 receiver_hint, tail_call_mode); |
1338 Node* value = ProcessCallArguments(call, args, arg_count); | 1330 Node* value = ProcessCallArguments(call, callee, receiver, arg_count + 1); |
1339 environment()->BindAccumulator(value, Environment::kAttachFrameState); | 1331 environment()->BindAccumulator(value, Environment::kAttachFrameState); |
1340 } | 1332 } |
1341 | 1333 |
1342 void BytecodeGraphBuilder::BuildCallVarArgs(TailCallMode tail_call_mode, | |
1343 ConvertReceiverMode receiver_hint) { | |
1344 Node* callee = | |
1345 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); | |
1346 interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1); | |
1347 size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2); | |
1348 int const slot_id = bytecode_iterator().GetIndexOperand(3); | |
1349 BuildCall(tail_call_mode, receiver_hint, | |
1350 GetCallArgumentsFromRegister(callee, receiver, arg_count + 1), | |
1351 arg_count + 1, slot_id); | |
1352 } | |
1353 | |
1354 void BytecodeGraphBuilder::VisitCall() { | 1334 void BytecodeGraphBuilder::VisitCall() { |
1355 BuildCallVarArgs(TailCallMode::kDisallow, ConvertReceiverMode::kAny); | 1335 BuildCall(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); | |
1433 } | 1336 } |
1434 | 1337 |
1435 void BytecodeGraphBuilder::VisitCallWithSpread() { | 1338 void BytecodeGraphBuilder::VisitCallWithSpread() { |
1436 PrepareEagerCheckpoint(); | 1339 PrepareEagerCheckpoint(); |
1437 Node* callee = | 1340 Node* callee = |
1438 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); | 1341 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); |
1439 interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1); | 1342 interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1); |
1440 size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2); | 1343 size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2); |
1441 const Operator* call = | 1344 const Operator* call = |
1442 javascript()->CallWithSpread(static_cast<int>(arg_count + 1)); | 1345 javascript()->CallWithSpread(static_cast<int>(arg_count + 1)); |
1443 | 1346 |
1444 Node* value = ProcessCallArguments(call, callee, receiver, arg_count + 1); | 1347 Node* value = ProcessCallArguments(call, callee, receiver, arg_count + 1); |
1445 environment()->BindAccumulator(value, Environment::kAttachFrameState); | 1348 environment()->BindAccumulator(value, Environment::kAttachFrameState); |
1446 } | 1349 } |
1447 | 1350 |
| 1351 void BytecodeGraphBuilder::VisitCallProperty() { |
| 1352 BuildCall(TailCallMode::kDisallow, ConvertReceiverMode::kNotNullOrUndefined); |
| 1353 } |
| 1354 |
1448 void BytecodeGraphBuilder::VisitTailCall() { | 1355 void BytecodeGraphBuilder::VisitTailCall() { |
1449 TailCallMode tail_call_mode = | 1356 TailCallMode tail_call_mode = |
1450 bytecode_array_->GetIsolate()->is_tail_call_elimination_enabled() | 1357 bytecode_array_->GetIsolate()->is_tail_call_elimination_enabled() |
1451 ? TailCallMode::kAllow | 1358 ? TailCallMode::kAllow |
1452 : TailCallMode::kDisallow; | 1359 : TailCallMode::kDisallow; |
1453 BuildCallVarArgs(tail_call_mode, ConvertReceiverMode::kAny); | 1360 BuildCall(tail_call_mode, ConvertReceiverMode::kAny); |
1454 } | 1361 } |
1455 | 1362 |
1456 void BytecodeGraphBuilder::VisitCallJSRuntime() { | 1363 void BytecodeGraphBuilder::VisitCallJSRuntime() { |
1457 PrepareEagerCheckpoint(); | 1364 PrepareEagerCheckpoint(); |
1458 Node* callee = | 1365 Node* callee = |
1459 BuildLoadNativeContextField(bytecode_iterator().GetIndexOperand(0)); | 1366 BuildLoadNativeContextField(bytecode_iterator().GetIndexOperand(0)); |
1460 interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1); | 1367 interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1); |
1461 size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2); | 1368 size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2); |
1462 | 1369 |
1463 // Create node to perform the JS runtime call. | 1370 // Create node to perform the JS runtime call. |
(...skipping 869 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2333 int next_end = table->GetRangeEnd(current_exception_handler_); | 2240 int next_end = table->GetRangeEnd(current_exception_handler_); |
2334 int next_handler = table->GetRangeHandler(current_exception_handler_); | 2241 int next_handler = table->GetRangeHandler(current_exception_handler_); |
2335 int context_register = table->GetRangeData(current_exception_handler_); | 2242 int context_register = table->GetRangeData(current_exception_handler_); |
2336 exception_handlers_.push( | 2243 exception_handlers_.push( |
2337 {next_start, next_end, next_handler, context_register}); | 2244 {next_start, next_end, next_handler, context_register}); |
2338 current_exception_handler_++; | 2245 current_exception_handler_++; |
2339 } | 2246 } |
2340 } | 2247 } |
2341 | 2248 |
2342 Node* BytecodeGraphBuilder::MakeNode(const Operator* op, int value_input_count, | 2249 Node* BytecodeGraphBuilder::MakeNode(const Operator* op, int value_input_count, |
2343 Node* const* value_inputs, | 2250 Node** value_inputs, bool incomplete) { |
2344 bool incomplete) { | |
2345 DCHECK_EQ(op->ValueInputCount(), value_input_count); | 2251 DCHECK_EQ(op->ValueInputCount(), value_input_count); |
2346 | 2252 |
2347 bool has_context = OperatorProperties::HasContextInput(op); | 2253 bool has_context = OperatorProperties::HasContextInput(op); |
2348 bool has_frame_state = OperatorProperties::HasFrameStateInput(op); | 2254 bool has_frame_state = OperatorProperties::HasFrameStateInput(op); |
2349 bool has_control = op->ControlInputCount() == 1; | 2255 bool has_control = op->ControlInputCount() == 1; |
2350 bool has_effect = op->EffectInputCount() == 1; | 2256 bool has_effect = op->EffectInputCount() == 1; |
2351 | 2257 |
2352 DCHECK_LT(op->ControlInputCount(), 2); | 2258 DCHECK_LT(op->ControlInputCount(), 2); |
2353 DCHECK_LT(op->EffectInputCount(), 2); | 2259 DCHECK_LT(op->EffectInputCount(), 2); |
2354 | 2260 |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2506 it->source_position().ScriptOffset(), start_position_.InliningId())); | 2412 it->source_position().ScriptOffset(), start_position_.InliningId())); |
2507 it->Advance(); | 2413 it->Advance(); |
2508 } else { | 2414 } else { |
2509 DCHECK_GT(it->code_offset(), offset); | 2415 DCHECK_GT(it->code_offset(), offset); |
2510 } | 2416 } |
2511 } | 2417 } |
2512 | 2418 |
2513 } // namespace compiler | 2419 } // namespace compiler |
2514 } // namespace internal | 2420 } // namespace internal |
2515 } // namespace v8 | 2421 } // namespace v8 |
OLD | NEW |