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 1261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1272 // only an estimate and does not match {ObjectLiteral::properties_count}. | 1272 // only an estimate and does not match {ObjectLiteral::properties_count}. |
1273 int number_of_properties = constant_properties->size(); | 1273 int number_of_properties = constant_properties->size(); |
1274 Node* literal = NewNode( | 1274 Node* literal = NewNode( |
1275 javascript()->CreateLiteralObject(constant_properties, literal_flags, | 1275 javascript()->CreateLiteralObject(constant_properties, literal_flags, |
1276 literal_index, number_of_properties), | 1276 literal_index, number_of_properties), |
1277 GetFunctionClosure()); | 1277 GetFunctionClosure()); |
1278 environment()->BindRegister(bytecode_iterator().GetRegisterOperand(3), | 1278 environment()->BindRegister(bytecode_iterator().GetRegisterOperand(3), |
1279 literal, Environment::kAttachFrameState); | 1279 literal, Environment::kAttachFrameState); |
1280 } | 1280 } |
1281 | 1281 |
1282 Node* BytecodeGraphBuilder::ProcessCallArguments(const Operator* call_op, | 1282 Node* const* BytecodeGraphBuilder::GetCallArgumentsFromRegister( |
1283 Node* callee, | 1283 Node* callee, interpreter::Register receiver, size_t arity) { |
1284 interpreter::Register receiver, | |
1285 size_t arity) { | |
1286 Node** all = local_zone()->NewArray<Node*>(static_cast<int>(arity)); | 1284 Node** all = local_zone()->NewArray<Node*>(static_cast<int>(arity)); |
1287 all[0] = callee; | 1285 all[0] = callee; |
1288 all[1] = environment()->LookupRegister(receiver); | 1286 all[1] = environment()->LookupRegister(receiver); |
1289 int receiver_index = receiver.index(); | 1287 int receiver_index = receiver.index(); |
1290 for (int i = 2; i < static_cast<int>(arity); ++i) { | 1288 for (int i = 2; i < static_cast<int>(arity); ++i) { |
1291 all[i] = environment()->LookupRegister( | 1289 all[i] = environment()->LookupRegister( |
1292 interpreter::Register(receiver_index + i - 1)); | 1290 interpreter::Register(receiver_index + i - 1)); |
1293 } | 1291 } |
1294 Node* value = MakeNode(call_op, static_cast<int>(arity), all, false); | 1292 return all; |
1295 return value; | 1293 } |
1294 | |
1295 Node* BytecodeGraphBuilder::ProcessCallArguments(const Operator* call_op, | |
1296 Node* const* args, | |
1297 size_t arg_count) { | |
1298 return MakeNode(call_op, static_cast<int>(arg_count), args, false); | |
1299 } | |
1300 | |
1301 Node* BytecodeGraphBuilder::ProcessCallArguments(const Operator* call_op, | |
1302 Node* callee, | |
1303 interpreter::Register receiver, | |
1304 size_t arg_count) { | |
1305 return ProcessCallArguments( | |
1306 call_op, GetCallArgumentsFromRegister(callee, receiver, arg_count), | |
1307 arg_count); | |
1308 } | |
1309 | |
1310 void BytecodeGraphBuilder::BuildCall(TailCallMode tail_call_mode, | |
1311 ConvertReceiverMode receiver_hint, | |
1312 Node* const* args, size_t arg_count, | |
1313 int slot_id) { | |
1314 PrepareEagerCheckpoint(); | |
1315 | |
1316 // Slot index of 0 is used indicate no feedback slot is available. Assert | |
1317 // the assumption that slot index 0 is never a valid feedback slot. | |
1318 STATIC_ASSERT(FeedbackVector::kReservedIndexCount > 0); | |
1319 VectorSlotPair feedback = CreateVectorSlotPair(slot_id); | |
1320 | |
1321 float const frequency = ComputeCallFrequency(slot_id); | |
1322 const Operator* call = javascript()->Call(arg_count, frequency, feedback, | |
1323 receiver_hint, tail_call_mode); | |
1324 Node* value = ProcessCallArguments(call, args, arg_count); | |
1325 environment()->BindAccumulator(value, Environment::kAttachFrameState); | |
1296 } | 1326 } |
1297 | 1327 |
1298 void BytecodeGraphBuilder::BuildCall(TailCallMode tail_call_mode, | 1328 void BytecodeGraphBuilder::BuildCall(TailCallMode tail_call_mode, |
rmcilroy
2017/02/17 11:37:19
nit - BuildCallN or something to specify this is f
danno
2017/02/17 17:18:43
Done.
| |
1299 ConvertReceiverMode receiver_hint) { | 1329 ConvertReceiverMode receiver_hint) { |
1300 PrepareEagerCheckpoint(); | |
1301 | |
1302 Node* callee = | 1330 Node* callee = |
1303 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); | 1331 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); |
1304 interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1); | 1332 interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1); |
1305 size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2); | 1333 size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2); |
1306 | |
1307 // Slot index of 0 is used indicate no feedback slot is available. Assert | |
1308 // the assumption that slot index 0 is never a valid feedback slot. | |
1309 STATIC_ASSERT(FeedbackVector::kReservedIndexCount > 0); | |
1310 int const slot_id = bytecode_iterator().GetIndexOperand(3); | 1334 int const slot_id = bytecode_iterator().GetIndexOperand(3); |
1311 VectorSlotPair feedback = CreateVectorSlotPair(slot_id); | 1335 BuildCall(tail_call_mode, receiver_hint, |
1312 | 1336 GetCallArgumentsFromRegister(callee, receiver, arg_count + 1), |
1313 float const frequency = ComputeCallFrequency(slot_id); | 1337 arg_count + 1, slot_id); |
1314 const Operator* call = javascript()->Call(arg_count + 1, frequency, feedback, | |
1315 receiver_hint, tail_call_mode); | |
1316 Node* value = ProcessCallArguments(call, callee, receiver, arg_count + 1); | |
1317 environment()->BindAccumulator(value, Environment::kAttachFrameState); | |
1318 } | 1338 } |
1319 | 1339 |
1320 void BytecodeGraphBuilder::VisitCall() { | 1340 void BytecodeGraphBuilder::VisitCall() { |
1321 BuildCall(TailCallMode::kDisallow, ConvertReceiverMode::kAny); | 1341 BuildCall(TailCallMode::kDisallow, ConvertReceiverMode::kAny); |
1322 } | 1342 } |
1323 | 1343 |
1344 void BytecodeGraphBuilder::VisitCall0() { | |
1345 Node* callee = | |
1346 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); | |
1347 Node* receiver = | |
1348 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1)); | |
1349 int const slot_id = bytecode_iterator().GetIndexOperand(2); | |
1350 BuildCall(TailCallMode::kDisallow, ConvertReceiverMode::kAny, | |
1351 {callee, receiver}, slot_id); | |
1352 } | |
1353 | |
1354 void BytecodeGraphBuilder::VisitCall1() { | |
1355 Node* callee = | |
1356 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); | |
1357 Node* receiver = | |
1358 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1)); | |
1359 Node* arg0 = | |
1360 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(2)); | |
1361 int const slot_id = bytecode_iterator().GetIndexOperand(3); | |
1362 BuildCall(TailCallMode::kDisallow, ConvertReceiverMode::kAny, | |
1363 {callee, receiver, arg0}, slot_id); | |
1364 } | |
1365 | |
1366 void BytecodeGraphBuilder::VisitCall2() { | |
1367 Node* callee = | |
1368 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); | |
1369 Node* receiver = | |
1370 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1)); | |
1371 Node* arg0 = | |
1372 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(2)); | |
1373 Node* arg1 = | |
1374 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(3)); | |
1375 int const slot_id = bytecode_iterator().GetIndexOperand(4); | |
1376 BuildCall(TailCallMode::kDisallow, ConvertReceiverMode::kAny, | |
1377 {callee, receiver, arg0, arg1}, slot_id); | |
1378 } | |
1379 | |
1380 void BytecodeGraphBuilder::VisitCallProperty() { | |
1381 BuildCall(TailCallMode::kDisallow, ConvertReceiverMode::kNotNullOrUndefined); | |
1382 } | |
1383 | |
1384 void BytecodeGraphBuilder::VisitCallProperty0() { | |
1385 Node* callee = | |
1386 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); | |
1387 Node* receiver = | |
1388 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1)); | |
1389 int const slot_id = bytecode_iterator().GetIndexOperand(2); | |
1390 BuildCall(TailCallMode::kDisallow, ConvertReceiverMode::kNotNullOrUndefined, | |
1391 {callee, receiver}, slot_id); | |
1392 } | |
1393 | |
1394 void BytecodeGraphBuilder::VisitCallProperty1() { | |
1395 Node* callee = | |
1396 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); | |
1397 Node* receiver = | |
1398 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1)); | |
1399 Node* arg0 = | |
1400 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(2)); | |
1401 int const slot_id = bytecode_iterator().GetIndexOperand(3); | |
1402 BuildCall(TailCallMode::kDisallow, ConvertReceiverMode::kNotNullOrUndefined, | |
1403 {callee, receiver, arg0}, slot_id); | |
1404 } | |
1405 | |
1406 void BytecodeGraphBuilder::VisitCallProperty2() { | |
1407 Node* callee = | |
1408 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); | |
1409 Node* receiver = | |
1410 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1)); | |
1411 Node* arg0 = | |
1412 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(2)); | |
1413 Node* arg1 = | |
1414 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(3)); | |
1415 int const slot_id = bytecode_iterator().GetIndexOperand(4); | |
1416 BuildCall(TailCallMode::kDisallow, ConvertReceiverMode::kNotNullOrUndefined, | |
1417 {callee, receiver, arg0, arg1}, slot_id); | |
1418 } | |
1419 | |
1324 void BytecodeGraphBuilder::VisitCallWithSpread() { | 1420 void BytecodeGraphBuilder::VisitCallWithSpread() { |
1325 PrepareEagerCheckpoint(); | 1421 PrepareEagerCheckpoint(); |
1326 Node* callee = | 1422 Node* callee = |
1327 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); | 1423 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); |
1328 interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1); | 1424 interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1); |
1329 size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2); | 1425 size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2); |
1330 const Operator* call = | 1426 const Operator* call = |
1331 javascript()->CallWithSpread(static_cast<int>(arg_count + 1)); | 1427 javascript()->CallWithSpread(static_cast<int>(arg_count + 1)); |
1332 | 1428 |
1333 Node* value = ProcessCallArguments(call, callee, receiver, arg_count + 1); | 1429 Node* value = ProcessCallArguments(call, callee, receiver, arg_count + 1); |
1334 environment()->BindAccumulator(value, Environment::kAttachFrameState); | 1430 environment()->BindAccumulator(value, Environment::kAttachFrameState); |
1335 } | 1431 } |
1336 | 1432 |
1337 void BytecodeGraphBuilder::VisitCallProperty() { | |
1338 BuildCall(TailCallMode::kDisallow, ConvertReceiverMode::kNotNullOrUndefined); | |
1339 } | |
1340 | |
1341 void BytecodeGraphBuilder::VisitTailCall() { | 1433 void BytecodeGraphBuilder::VisitTailCall() { |
1342 TailCallMode tail_call_mode = | 1434 TailCallMode tail_call_mode = |
1343 bytecode_array_->GetIsolate()->is_tail_call_elimination_enabled() | 1435 bytecode_array_->GetIsolate()->is_tail_call_elimination_enabled() |
1344 ? TailCallMode::kAllow | 1436 ? TailCallMode::kAllow |
1345 : TailCallMode::kDisallow; | 1437 : TailCallMode::kDisallow; |
1346 BuildCall(tail_call_mode, ConvertReceiverMode::kAny); | 1438 BuildCall(tail_call_mode, ConvertReceiverMode::kAny); |
1347 } | 1439 } |
1348 | 1440 |
1349 void BytecodeGraphBuilder::VisitCallJSRuntime() { | 1441 void BytecodeGraphBuilder::VisitCallJSRuntime() { |
1350 PrepareEagerCheckpoint(); | 1442 PrepareEagerCheckpoint(); |
(...skipping 875 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2226 int next_end = table->GetRangeEnd(current_exception_handler_); | 2318 int next_end = table->GetRangeEnd(current_exception_handler_); |
2227 int next_handler = table->GetRangeHandler(current_exception_handler_); | 2319 int next_handler = table->GetRangeHandler(current_exception_handler_); |
2228 int context_register = table->GetRangeData(current_exception_handler_); | 2320 int context_register = table->GetRangeData(current_exception_handler_); |
2229 exception_handlers_.push( | 2321 exception_handlers_.push( |
2230 {next_start, next_end, next_handler, context_register}); | 2322 {next_start, next_end, next_handler, context_register}); |
2231 current_exception_handler_++; | 2323 current_exception_handler_++; |
2232 } | 2324 } |
2233 } | 2325 } |
2234 | 2326 |
2235 Node* BytecodeGraphBuilder::MakeNode(const Operator* op, int value_input_count, | 2327 Node* BytecodeGraphBuilder::MakeNode(const Operator* op, int value_input_count, |
2236 Node** value_inputs, bool incomplete) { | 2328 Node* const* value_inputs, |
2329 bool incomplete) { | |
2237 DCHECK_EQ(op->ValueInputCount(), value_input_count); | 2330 DCHECK_EQ(op->ValueInputCount(), value_input_count); |
2238 | 2331 |
2239 bool has_context = OperatorProperties::HasContextInput(op); | 2332 bool has_context = OperatorProperties::HasContextInput(op); |
2240 bool has_frame_state = OperatorProperties::HasFrameStateInput(op); | 2333 bool has_frame_state = OperatorProperties::HasFrameStateInput(op); |
2241 bool has_control = op->ControlInputCount() == 1; | 2334 bool has_control = op->ControlInputCount() == 1; |
2242 bool has_effect = op->EffectInputCount() == 1; | 2335 bool has_effect = op->EffectInputCount() == 1; |
2243 | 2336 |
2244 DCHECK_LT(op->ControlInputCount(), 2); | 2337 DCHECK_LT(op->ControlInputCount(), 2); |
2245 DCHECK_LT(op->EffectInputCount(), 2); | 2338 DCHECK_LT(op->EffectInputCount(), 2); |
2246 | 2339 |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2398 it->source_position().ScriptOffset(), start_position_.InliningId())); | 2491 it->source_position().ScriptOffset(), start_position_.InliningId())); |
2399 it->Advance(); | 2492 it->Advance(); |
2400 } else { | 2493 } else { |
2401 DCHECK_GT(it->code_offset(), offset); | 2494 DCHECK_GT(it->code_offset(), offset); |
2402 } | 2495 } |
2403 } | 2496 } |
2404 | 2497 |
2405 } // namespace compiler | 2498 } // namespace compiler |
2406 } // namespace internal | 2499 } // namespace internal |
2407 } // namespace v8 | 2500 } // namespace v8 |
OLD | NEW |