| 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 |