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 1213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1224 // only an estimate and does not match {ObjectLiteral::properties_count}. | 1224 // only an estimate and does not match {ObjectLiteral::properties_count}. |
1225 int number_of_properties = constant_properties->size(); | 1225 int number_of_properties = constant_properties->size(); |
1226 Node* literal = NewNode( | 1226 Node* literal = NewNode( |
1227 javascript()->CreateLiteralObject(constant_properties, literal_flags, | 1227 javascript()->CreateLiteralObject(constant_properties, literal_flags, |
1228 literal_index, number_of_properties), | 1228 literal_index, number_of_properties), |
1229 GetFunctionClosure()); | 1229 GetFunctionClosure()); |
1230 environment()->BindRegister(bytecode_iterator().GetRegisterOperand(3), | 1230 environment()->BindRegister(bytecode_iterator().GetRegisterOperand(3), |
1231 literal, Environment::kAttachFrameState); | 1231 literal, Environment::kAttachFrameState); |
1232 } | 1232 } |
1233 | 1233 |
1234 Node* BytecodeGraphBuilder::ProcessCallArguments(const Operator* call_op, | 1234 Node* const* BytecodeGraphBuilder::GetCallArgumentsFromRegister( |
1235 Node* callee, | 1235 Node* callee, interpreter::Register receiver, size_t arity) { |
1236 interpreter::Register receiver, | |
1237 size_t arity) { | |
1238 Node** all = local_zone()->NewArray<Node*>(static_cast<int>(arity)); | 1236 Node** all = local_zone()->NewArray<Node*>(static_cast<int>(arity)); |
1239 all[0] = callee; | 1237 all[0] = callee; |
1240 all[1] = environment()->LookupRegister(receiver); | 1238 all[1] = environment()->LookupRegister(receiver); |
1241 int receiver_index = receiver.index(); | 1239 int receiver_index = receiver.index(); |
1242 for (int i = 2; i < static_cast<int>(arity); ++i) { | 1240 for (int i = 2; i < static_cast<int>(arity); ++i) { |
1243 all[i] = environment()->LookupRegister( | 1241 all[i] = environment()->LookupRegister( |
1244 interpreter::Register(receiver_index + i - 1)); | 1242 interpreter::Register(receiver_index + i - 1)); |
1245 } | 1243 } |
1246 Node* value = MakeNode(call_op, static_cast<int>(arity), all, false); | 1244 return all; |
1247 return value; | 1245 } |
| 1246 |
| 1247 Node* BytecodeGraphBuilder::ProcessCallArguments(const Operator* call_op, |
| 1248 Node* const* args, |
| 1249 size_t arg_count) { |
| 1250 return MakeNode(call_op, static_cast<int>(arg_count), args, false); |
| 1251 } |
| 1252 |
| 1253 Node* BytecodeGraphBuilder::ProcessCallArguments(const Operator* call_op, |
| 1254 Node* callee, |
| 1255 interpreter::Register receiver, |
| 1256 size_t arg_count) { |
| 1257 return ProcessCallArguments( |
| 1258 call_op, GetCallArgumentsFromRegister(callee, receiver, arg_count), |
| 1259 arg_count); |
| 1260 } |
| 1261 |
| 1262 void BytecodeGraphBuilder::BuildCall(TailCallMode tail_call_mode, |
| 1263 ConvertReceiverMode receiver_hint, |
| 1264 Node* const* args, size_t arg_count, |
| 1265 int slot_id) { |
| 1266 PrepareEagerCheckpoint(); |
| 1267 |
| 1268 // Slot index of 0 is used indicate no feedback slot is available. Assert |
| 1269 // the assumption that slot index 0 is never a valid feedback slot. |
| 1270 STATIC_ASSERT(TypeFeedbackVector::kReservedIndexCount > 0); |
| 1271 VectorSlotPair feedback = CreateVectorSlotPair(slot_id); |
| 1272 |
| 1273 float const frequency = ComputeCallFrequency(slot_id); |
| 1274 const Operator* call = javascript()->Call(arg_count, frequency, feedback, |
| 1275 receiver_hint, tail_call_mode); |
| 1276 Node* value = ProcessCallArguments(call, args, arg_count); |
| 1277 environment()->BindAccumulator(value, Environment::kAttachFrameState); |
1248 } | 1278 } |
1249 | 1279 |
1250 void BytecodeGraphBuilder::BuildCall(TailCallMode tail_call_mode, | 1280 void BytecodeGraphBuilder::BuildCall(TailCallMode tail_call_mode, |
1251 ConvertReceiverMode receiver_hint) { | 1281 ConvertReceiverMode receiver_hint) { |
1252 PrepareEagerCheckpoint(); | |
1253 | |
1254 Node* callee = | 1282 Node* callee = |
1255 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); | 1283 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); |
1256 interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1); | 1284 interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1); |
1257 size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2); | 1285 size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2); |
1258 | |
1259 // Slot index of 0 is used indicate no feedback slot is available. Assert | |
1260 // the assumption that slot index 0 is never a valid feedback slot. | |
1261 STATIC_ASSERT(TypeFeedbackVector::kReservedIndexCount > 0); | |
1262 int const slot_id = bytecode_iterator().GetIndexOperand(3); | 1286 int const slot_id = bytecode_iterator().GetIndexOperand(3); |
1263 VectorSlotPair feedback = CreateVectorSlotPair(slot_id); | 1287 BuildCall(tail_call_mode, receiver_hint, |
1264 | 1288 GetCallArgumentsFromRegister(callee, receiver, arg_count + 1), |
1265 float const frequency = ComputeCallFrequency(slot_id); | 1289 arg_count + 1, slot_id); |
1266 const Operator* call = javascript()->Call(arg_count + 1, frequency, feedback, | |
1267 receiver_hint, tail_call_mode); | |
1268 Node* value = ProcessCallArguments(call, callee, receiver, arg_count + 1); | |
1269 environment()->BindAccumulator(value, Environment::kAttachFrameState); | |
1270 } | 1290 } |
1271 | 1291 |
1272 void BytecodeGraphBuilder::VisitCall() { | 1292 void BytecodeGraphBuilder::VisitCall() { |
1273 BuildCall(TailCallMode::kDisallow, ConvertReceiverMode::kAny); | 1293 BuildCall(TailCallMode::kDisallow, ConvertReceiverMode::kAny); |
1274 } | 1294 } |
1275 | 1295 |
| 1296 void BytecodeGraphBuilder::VisitCall0() { |
| 1297 Node* callee = |
| 1298 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); |
| 1299 Node* receiver = |
| 1300 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1)); |
| 1301 int const slot_id = bytecode_iterator().GetIndexOperand(2); |
| 1302 BuildCall(TailCallMode::kDisallow, ConvertReceiverMode::kAny, |
| 1303 {callee, receiver}, slot_id); |
| 1304 } |
| 1305 |
| 1306 void BytecodeGraphBuilder::VisitCall1() { |
| 1307 Node* callee = |
| 1308 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); |
| 1309 Node* receiver = |
| 1310 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1)); |
| 1311 Node* arg0 = |
| 1312 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(2)); |
| 1313 int const slot_id = bytecode_iterator().GetIndexOperand(3); |
| 1314 BuildCall(TailCallMode::kDisallow, ConvertReceiverMode::kAny, |
| 1315 {callee, receiver, arg0}, slot_id); |
| 1316 } |
| 1317 |
| 1318 void BytecodeGraphBuilder::VisitCall2() { |
| 1319 Node* callee = |
| 1320 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); |
| 1321 Node* receiver = |
| 1322 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1)); |
| 1323 Node* arg0 = |
| 1324 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(2)); |
| 1325 Node* arg1 = |
| 1326 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(3)); |
| 1327 int const slot_id = bytecode_iterator().GetIndexOperand(4); |
| 1328 BuildCall(TailCallMode::kDisallow, ConvertReceiverMode::kAny, |
| 1329 {callee, receiver, arg0, arg1}, slot_id); |
| 1330 } |
| 1331 |
1276 void BytecodeGraphBuilder::VisitCallWithSpread() { | 1332 void BytecodeGraphBuilder::VisitCallWithSpread() { |
1277 PrepareEagerCheckpoint(); | 1333 PrepareEagerCheckpoint(); |
1278 Node* callee = | 1334 Node* callee = |
1279 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); | 1335 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); |
1280 interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1); | 1336 interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1); |
1281 size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2); | 1337 size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2); |
1282 const Operator* call = | 1338 const Operator* call = |
1283 javascript()->CallWithSpread(static_cast<int>(arg_count + 1)); | 1339 javascript()->CallWithSpread(static_cast<int>(arg_count + 1)); |
1284 | 1340 |
1285 Node* value = ProcessCallArguments(call, callee, receiver, arg_count + 1); | 1341 Node* value = ProcessCallArguments(call, callee, receiver, arg_count + 1); |
(...skipping 846 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2132 int next_end = table->GetRangeEnd(current_exception_handler_); | 2188 int next_end = table->GetRangeEnd(current_exception_handler_); |
2133 int next_handler = table->GetRangeHandler(current_exception_handler_); | 2189 int next_handler = table->GetRangeHandler(current_exception_handler_); |
2134 int context_register = table->GetRangeData(current_exception_handler_); | 2190 int context_register = table->GetRangeData(current_exception_handler_); |
2135 exception_handlers_.push( | 2191 exception_handlers_.push( |
2136 {next_start, next_end, next_handler, context_register}); | 2192 {next_start, next_end, next_handler, context_register}); |
2137 current_exception_handler_++; | 2193 current_exception_handler_++; |
2138 } | 2194 } |
2139 } | 2195 } |
2140 | 2196 |
2141 Node* BytecodeGraphBuilder::MakeNode(const Operator* op, int value_input_count, | 2197 Node* BytecodeGraphBuilder::MakeNode(const Operator* op, int value_input_count, |
2142 Node** value_inputs, bool incomplete) { | 2198 Node* const* value_inputs, |
| 2199 bool incomplete) { |
2143 DCHECK_EQ(op->ValueInputCount(), value_input_count); | 2200 DCHECK_EQ(op->ValueInputCount(), value_input_count); |
2144 | 2201 |
2145 bool has_context = OperatorProperties::HasContextInput(op); | 2202 bool has_context = OperatorProperties::HasContextInput(op); |
2146 bool has_frame_state = OperatorProperties::HasFrameStateInput(op); | 2203 bool has_frame_state = OperatorProperties::HasFrameStateInput(op); |
2147 bool has_control = op->ControlInputCount() == 1; | 2204 bool has_control = op->ControlInputCount() == 1; |
2148 bool has_effect = op->EffectInputCount() == 1; | 2205 bool has_effect = op->EffectInputCount() == 1; |
2149 | 2206 |
2150 DCHECK_LT(op->ControlInputCount(), 2); | 2207 DCHECK_LT(op->ControlInputCount(), 2); |
2151 DCHECK_LT(op->EffectInputCount(), 2); | 2208 DCHECK_LT(op->EffectInputCount(), 2); |
2152 | 2209 |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2300 it->source_position().ScriptOffset(), start_position_.InliningId())); | 2357 it->source_position().ScriptOffset(), start_position_.InliningId())); |
2301 it->Advance(); | 2358 it->Advance(); |
2302 } else { | 2359 } else { |
2303 DCHECK_GT(it->code_offset(), offset); | 2360 DCHECK_GT(it->code_offset(), offset); |
2304 } | 2361 } |
2305 } | 2362 } |
2306 | 2363 |
2307 } // namespace compiler | 2364 } // namespace compiler |
2308 } // namespace internal | 2365 } // namespace internal |
2309 } // namespace v8 | 2366 } // namespace v8 |
OLD | NEW |