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 1214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1225 // only an estimate and does not match {ObjectLiteral::properties_count}. | 1225 // only an estimate and does not match {ObjectLiteral::properties_count}. |
1226 int number_of_properties = constant_properties->size(); | 1226 int number_of_properties = constant_properties->size(); |
1227 Node* literal = NewNode( | 1227 Node* literal = NewNode( |
1228 javascript()->CreateLiteralObject(constant_properties, literal_flags, | 1228 javascript()->CreateLiteralObject(constant_properties, literal_flags, |
1229 literal_index, number_of_properties), | 1229 literal_index, number_of_properties), |
1230 GetFunctionClosure()); | 1230 GetFunctionClosure()); |
1231 environment()->BindRegister(bytecode_iterator().GetRegisterOperand(3), | 1231 environment()->BindRegister(bytecode_iterator().GetRegisterOperand(3), |
1232 literal, Environment::kAttachFrameState); | 1232 literal, Environment::kAttachFrameState); |
1233 } | 1233 } |
1234 | 1234 |
1235 Node* BytecodeGraphBuilder::ProcessCallArguments(const Operator* call_op, | 1235 Node* const* BytecodeGraphBuilder::GetCallArgumentsFromRegister( |
1236 Node* callee, | 1236 Node* callee, interpreter::Register receiver, size_t arity) { |
1237 interpreter::Register receiver, | |
1238 size_t arity) { | |
1239 Node** all = local_zone()->NewArray<Node*>(static_cast<int>(arity)); | 1237 Node** all = local_zone()->NewArray<Node*>(static_cast<int>(arity)); |
1240 all[0] = callee; | 1238 all[0] = callee; |
1241 all[1] = environment()->LookupRegister(receiver); | 1239 all[1] = environment()->LookupRegister(receiver); |
1242 int receiver_index = receiver.index(); | 1240 int receiver_index = receiver.index(); |
1243 for (int i = 2; i < static_cast<int>(arity); ++i) { | 1241 for (int i = 2; i < static_cast<int>(arity); ++i) { |
1244 all[i] = environment()->LookupRegister( | 1242 all[i] = environment()->LookupRegister( |
1245 interpreter::Register(receiver_index + i - 1)); | 1243 interpreter::Register(receiver_index + i - 1)); |
1246 } | 1244 } |
1247 Node* value = MakeNode(call_op, static_cast<int>(arity), all, false); | 1245 return all; |
1248 return value; | 1246 } |
| 1247 |
| 1248 Node* BytecodeGraphBuilder::ProcessCallArguments(const Operator* call_op, |
| 1249 Node* const* args, |
| 1250 size_t arg_count) { |
| 1251 return MakeNode(call_op, static_cast<int>(arg_count), args, false); |
| 1252 } |
| 1253 |
| 1254 Node* BytecodeGraphBuilder::ProcessCallArguments(const Operator* call_op, |
| 1255 Node* callee, |
| 1256 interpreter::Register receiver, |
| 1257 size_t arg_count) { |
| 1258 return ProcessCallArguments( |
| 1259 call_op, GetCallArgumentsFromRegister(callee, receiver, arg_count), |
| 1260 arg_count); |
| 1261 } |
| 1262 |
| 1263 void BytecodeGraphBuilder::BuildCall(TailCallMode tail_call_mode, |
| 1264 ConvertReceiverMode receiver_hint, |
| 1265 Node* const* args, size_t arg_count, |
| 1266 int slot_id) { |
| 1267 PrepareEagerCheckpoint(); |
| 1268 |
| 1269 // Slot index of 0 is used indicate no feedback slot is available. Assert |
| 1270 // the assumption that slot index 0 is never a valid feedback slot. |
| 1271 STATIC_ASSERT(TypeFeedbackVector::kReservedIndexCount > 0); |
| 1272 VectorSlotPair feedback = CreateVectorSlotPair(slot_id); |
| 1273 |
| 1274 float const frequency = ComputeCallFrequency(slot_id); |
| 1275 const Operator* call = javascript()->Call(arg_count, frequency, feedback, |
| 1276 receiver_hint, tail_call_mode); |
| 1277 Node* value = ProcessCallArguments(call, args, arg_count); |
| 1278 environment()->BindAccumulator(value, Environment::kAttachFrameState); |
1249 } | 1279 } |
1250 | 1280 |
1251 void BytecodeGraphBuilder::BuildCall(TailCallMode tail_call_mode, | 1281 void BytecodeGraphBuilder::BuildCall(TailCallMode tail_call_mode, |
1252 ConvertReceiverMode receiver_hint) { | 1282 ConvertReceiverMode receiver_hint) { |
1253 PrepareEagerCheckpoint(); | |
1254 | |
1255 Node* callee = | 1283 Node* callee = |
1256 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); | 1284 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); |
1257 interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1); | 1285 interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1); |
1258 size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2); | 1286 size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2); |
1259 | |
1260 // Slot index of 0 is used indicate no feedback slot is available. Assert | |
1261 // the assumption that slot index 0 is never a valid feedback slot. | |
1262 STATIC_ASSERT(TypeFeedbackVector::kReservedIndexCount > 0); | |
1263 int const slot_id = bytecode_iterator().GetIndexOperand(3); | 1287 int const slot_id = bytecode_iterator().GetIndexOperand(3); |
1264 VectorSlotPair feedback = CreateVectorSlotPair(slot_id); | 1288 BuildCall(tail_call_mode, receiver_hint, |
1265 | 1289 GetCallArgumentsFromRegister(callee, receiver, arg_count + 1), |
1266 float const frequency = ComputeCallFrequency(slot_id); | 1290 arg_count + 1, slot_id); |
1267 const Operator* call = javascript()->Call(arg_count + 1, frequency, feedback, | |
1268 receiver_hint, tail_call_mode); | |
1269 Node* value = ProcessCallArguments(call, callee, receiver, arg_count + 1); | |
1270 environment()->BindAccumulator(value, Environment::kAttachFrameState); | |
1271 } | 1291 } |
1272 | 1292 |
1273 void BytecodeGraphBuilder::VisitCall() { | 1293 void BytecodeGraphBuilder::VisitCall() { |
1274 BuildCall(TailCallMode::kDisallow, ConvertReceiverMode::kAny); | 1294 BuildCall(TailCallMode::kDisallow, ConvertReceiverMode::kAny); |
1275 } | 1295 } |
1276 | 1296 |
| 1297 void BytecodeGraphBuilder::VisitCall0() { |
| 1298 Node* callee = |
| 1299 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); |
| 1300 Node* receiver = |
| 1301 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1)); |
| 1302 int const slot_id = bytecode_iterator().GetIndexOperand(2); |
| 1303 BuildCall(TailCallMode::kDisallow, ConvertReceiverMode::kAny, |
| 1304 {callee, receiver}, slot_id); |
| 1305 } |
| 1306 |
| 1307 void BytecodeGraphBuilder::VisitCall1() { |
| 1308 Node* callee = |
| 1309 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); |
| 1310 Node* receiver = |
| 1311 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1)); |
| 1312 Node* arg0 = |
| 1313 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(2)); |
| 1314 int const slot_id = bytecode_iterator().GetIndexOperand(3); |
| 1315 BuildCall(TailCallMode::kDisallow, ConvertReceiverMode::kAny, |
| 1316 {callee, receiver, arg0}, slot_id); |
| 1317 } |
| 1318 |
| 1319 void BytecodeGraphBuilder::VisitCall2() { |
| 1320 Node* callee = |
| 1321 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); |
| 1322 Node* receiver = |
| 1323 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1)); |
| 1324 Node* arg0 = |
| 1325 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(2)); |
| 1326 Node* arg1 = |
| 1327 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(3)); |
| 1328 int const slot_id = bytecode_iterator().GetIndexOperand(4); |
| 1329 BuildCall(TailCallMode::kDisallow, ConvertReceiverMode::kAny, |
| 1330 {callee, receiver, arg0, arg1}, slot_id); |
| 1331 } |
| 1332 |
| 1333 void BytecodeGraphBuilder::VisitCallProperty() { |
| 1334 BuildCall(TailCallMode::kDisallow, ConvertReceiverMode::kNotNullOrUndefined); |
| 1335 } |
| 1336 |
| 1337 void BytecodeGraphBuilder::VisitCallProperty0() { |
| 1338 Node* callee = |
| 1339 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); |
| 1340 Node* receiver = |
| 1341 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1)); |
| 1342 int const slot_id = bytecode_iterator().GetIndexOperand(2); |
| 1343 BuildCall(TailCallMode::kDisallow, ConvertReceiverMode::kNotNullOrUndefined, |
| 1344 {callee, receiver}, slot_id); |
| 1345 } |
| 1346 |
| 1347 void BytecodeGraphBuilder::VisitCallProperty1() { |
| 1348 Node* callee = |
| 1349 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); |
| 1350 Node* receiver = |
| 1351 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1)); |
| 1352 Node* arg0 = |
| 1353 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(2)); |
| 1354 int const slot_id = bytecode_iterator().GetIndexOperand(3); |
| 1355 BuildCall(TailCallMode::kDisallow, ConvertReceiverMode::kNotNullOrUndefined, |
| 1356 {callee, receiver, arg0}, slot_id); |
| 1357 } |
| 1358 |
| 1359 void BytecodeGraphBuilder::VisitCallProperty2() { |
| 1360 Node* callee = |
| 1361 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); |
| 1362 Node* receiver = |
| 1363 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1)); |
| 1364 Node* arg0 = |
| 1365 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(2)); |
| 1366 Node* arg1 = |
| 1367 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(3)); |
| 1368 int const slot_id = bytecode_iterator().GetIndexOperand(4); |
| 1369 BuildCall(TailCallMode::kDisallow, ConvertReceiverMode::kNotNullOrUndefined, |
| 1370 {callee, receiver, arg0, arg1}, slot_id); |
| 1371 } |
| 1372 |
1277 void BytecodeGraphBuilder::VisitCallWithSpread() { | 1373 void BytecodeGraphBuilder::VisitCallWithSpread() { |
1278 PrepareEagerCheckpoint(); | 1374 PrepareEagerCheckpoint(); |
1279 Node* callee = | 1375 Node* callee = |
1280 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); | 1376 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); |
1281 interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1); | 1377 interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1); |
1282 size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2); | 1378 size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2); |
1283 const Operator* call = | 1379 const Operator* call = |
1284 javascript()->CallWithSpread(static_cast<int>(arg_count + 1)); | 1380 javascript()->CallWithSpread(static_cast<int>(arg_count + 1)); |
1285 | 1381 |
1286 Node* value = ProcessCallArguments(call, callee, receiver, arg_count + 1); | 1382 Node* value = ProcessCallArguments(call, callee, receiver, arg_count + 1); |
1287 environment()->BindAccumulator(value, Environment::kAttachFrameState); | 1383 environment()->BindAccumulator(value, Environment::kAttachFrameState); |
1288 } | 1384 } |
1289 | 1385 |
1290 void BytecodeGraphBuilder::VisitCallProperty() { | |
1291 BuildCall(TailCallMode::kDisallow, ConvertReceiverMode::kNotNullOrUndefined); | |
1292 } | |
1293 | |
1294 void BytecodeGraphBuilder::VisitTailCall() { | 1386 void BytecodeGraphBuilder::VisitTailCall() { |
1295 TailCallMode tail_call_mode = | 1387 TailCallMode tail_call_mode = |
1296 bytecode_array_->GetIsolate()->is_tail_call_elimination_enabled() | 1388 bytecode_array_->GetIsolate()->is_tail_call_elimination_enabled() |
1297 ? TailCallMode::kAllow | 1389 ? TailCallMode::kAllow |
1298 : TailCallMode::kDisallow; | 1390 : TailCallMode::kDisallow; |
1299 BuildCall(tail_call_mode, ConvertReceiverMode::kAny); | 1391 BuildCall(tail_call_mode, ConvertReceiverMode::kAny); |
1300 } | 1392 } |
1301 | 1393 |
1302 void BytecodeGraphBuilder::VisitCallJSRuntime() { | 1394 void BytecodeGraphBuilder::VisitCallJSRuntime() { |
1303 PrepareEagerCheckpoint(); | 1395 PrepareEagerCheckpoint(); |
(...skipping 843 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2147 int next_end = table->GetRangeEnd(current_exception_handler_); | 2239 int next_end = table->GetRangeEnd(current_exception_handler_); |
2148 int next_handler = table->GetRangeHandler(current_exception_handler_); | 2240 int next_handler = table->GetRangeHandler(current_exception_handler_); |
2149 int context_register = table->GetRangeData(current_exception_handler_); | 2241 int context_register = table->GetRangeData(current_exception_handler_); |
2150 exception_handlers_.push( | 2242 exception_handlers_.push( |
2151 {next_start, next_end, next_handler, context_register}); | 2243 {next_start, next_end, next_handler, context_register}); |
2152 current_exception_handler_++; | 2244 current_exception_handler_++; |
2153 } | 2245 } |
2154 } | 2246 } |
2155 | 2247 |
2156 Node* BytecodeGraphBuilder::MakeNode(const Operator* op, int value_input_count, | 2248 Node* BytecodeGraphBuilder::MakeNode(const Operator* op, int value_input_count, |
2157 Node** value_inputs, bool incomplete) { | 2249 Node* const* value_inputs, |
| 2250 bool incomplete) { |
2158 DCHECK_EQ(op->ValueInputCount(), value_input_count); | 2251 DCHECK_EQ(op->ValueInputCount(), value_input_count); |
2159 | 2252 |
2160 bool has_context = OperatorProperties::HasContextInput(op); | 2253 bool has_context = OperatorProperties::HasContextInput(op); |
2161 bool has_frame_state = OperatorProperties::HasFrameStateInput(op); | 2254 bool has_frame_state = OperatorProperties::HasFrameStateInput(op); |
2162 bool has_control = op->ControlInputCount() == 1; | 2255 bool has_control = op->ControlInputCount() == 1; |
2163 bool has_effect = op->EffectInputCount() == 1; | 2256 bool has_effect = op->EffectInputCount() == 1; |
2164 | 2257 |
2165 DCHECK_LT(op->ControlInputCount(), 2); | 2258 DCHECK_LT(op->ControlInputCount(), 2); |
2166 DCHECK_LT(op->EffectInputCount(), 2); | 2259 DCHECK_LT(op->EffectInputCount(), 2); |
2167 | 2260 |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2315 it->source_position().ScriptOffset(), start_position_.InliningId())); | 2408 it->source_position().ScriptOffset(), start_position_.InliningId())); |
2316 it->Advance(); | 2409 it->Advance(); |
2317 } else { | 2410 } else { |
2318 DCHECK_GT(it->code_offset(), offset); | 2411 DCHECK_GT(it->code_offset(), offset); |
2319 } | 2412 } |
2320 } | 2413 } |
2321 | 2414 |
2322 } // namespace compiler | 2415 } // namespace compiler |
2323 } // namespace internal | 2416 } // namespace internal |
2324 } // namespace v8 | 2417 } // namespace v8 |
OLD | NEW |