OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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/js-operator.h" | 5 #include "src/compiler/js-operator.h" |
6 | 6 |
7 #include <limits> | 7 #include <limits> |
8 | 8 |
9 #include "src/base/lazy-instance.h" | 9 #include "src/base/lazy-instance.h" |
10 #include "src/compiler/opcodes.h" | 10 #include "src/compiler/opcodes.h" |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
201 return os << p.strict_mode() << ", " << Brief(*p.name().handle()); | 201 return os << p.strict_mode() << ", " << Brief(*p.name().handle()); |
202 } | 202 } |
203 | 203 |
204 | 204 |
205 const StoreNamedParameters& StoreNamedParametersOf(const Operator* op) { | 205 const StoreNamedParameters& StoreNamedParametersOf(const Operator* op) { |
206 DCHECK_EQ(IrOpcode::kJSStoreNamed, op->opcode()); | 206 DCHECK_EQ(IrOpcode::kJSStoreNamed, op->opcode()); |
207 return OpParameter<StoreNamedParameters>(op); | 207 return OpParameter<StoreNamedParameters>(op); |
208 } | 208 } |
209 | 209 |
210 | 210 |
211 #define SHARED_OP_LIST(V) \ | 211 #define CACHED_OP_LIST(V) \ |
212 V(Equal, Operator::kNoProperties, 2, 1) \ | 212 V(Equal, Operator::kNoProperties, 2, 1) \ |
213 V(NotEqual, Operator::kNoProperties, 2, 1) \ | 213 V(NotEqual, Operator::kNoProperties, 2, 1) \ |
214 V(StrictEqual, Operator::kPure, 2, 1) \ | 214 V(StrictEqual, Operator::kPure, 2, 1) \ |
215 V(StrictNotEqual, Operator::kPure, 2, 1) \ | 215 V(StrictNotEqual, Operator::kPure, 2, 1) \ |
216 V(LessThan, Operator::kNoProperties, 2, 1) \ | 216 V(LessThan, Operator::kNoProperties, 2, 1) \ |
217 V(GreaterThan, Operator::kNoProperties, 2, 1) \ | 217 V(GreaterThan, Operator::kNoProperties, 2, 1) \ |
218 V(LessThanOrEqual, Operator::kNoProperties, 2, 1) \ | 218 V(LessThanOrEqual, Operator::kNoProperties, 2, 1) \ |
219 V(GreaterThanOrEqual, Operator::kNoProperties, 2, 1) \ | 219 V(GreaterThanOrEqual, Operator::kNoProperties, 2, 1) \ |
220 V(BitwiseOr, Operator::kNoProperties, 2, 1) \ | 220 V(BitwiseOr, Operator::kNoProperties, 2, 1) \ |
221 V(BitwiseXor, Operator::kNoProperties, 2, 1) \ | 221 V(BitwiseXor, Operator::kNoProperties, 2, 1) \ |
(...skipping 18 matching lines...) Expand all Loading... |
240 V(TypeOf, Operator::kPure, 1, 1) \ | 240 V(TypeOf, Operator::kPure, 1, 1) \ |
241 V(InstanceOf, Operator::kNoProperties, 2, 1) \ | 241 V(InstanceOf, Operator::kNoProperties, 2, 1) \ |
242 V(Debugger, Operator::kNoProperties, 0, 0) \ | 242 V(Debugger, Operator::kNoProperties, 0, 0) \ |
243 V(CreateFunctionContext, Operator::kNoProperties, 1, 1) \ | 243 V(CreateFunctionContext, Operator::kNoProperties, 1, 1) \ |
244 V(CreateWithContext, Operator::kNoProperties, 2, 1) \ | 244 V(CreateWithContext, Operator::kNoProperties, 2, 1) \ |
245 V(CreateBlockContext, Operator::kNoProperties, 2, 1) \ | 245 V(CreateBlockContext, Operator::kNoProperties, 2, 1) \ |
246 V(CreateModuleContext, Operator::kNoProperties, 2, 1) \ | 246 V(CreateModuleContext, Operator::kNoProperties, 2, 1) \ |
247 V(CreateGlobalContext, Operator::kNoProperties, 2, 1) | 247 V(CreateGlobalContext, Operator::kNoProperties, 2, 1) |
248 | 248 |
249 | 249 |
250 struct JSOperatorBuilderImpl FINAL { | 250 struct JSOperatorGlobalCache FINAL { |
251 #define SHARED(Name, properties, value_input_count, value_output_count) \ | 251 #define CACHED(Name, properties, value_input_count, value_output_count) \ |
252 struct Name##Operator FINAL : public SimpleOperator { \ | 252 struct Name##Operator FINAL : public Operator { \ |
253 Name##Operator() \ | 253 Name##Operator() \ |
254 : SimpleOperator(IrOpcode::kJS##Name, properties, value_input_count, \ | 254 : Operator(IrOpcode::kJS##Name, properties, "JS" #Name, \ |
255 value_output_count, "JS" #Name) {} \ | 255 value_input_count, Operator::ZeroIfPure(properties), \ |
256 }; \ | 256 Operator::ZeroIfPure(properties), value_output_count, \ |
| 257 Operator::ZeroIfPure(properties), 0) {} \ |
| 258 }; \ |
257 Name##Operator k##Name##Operator; | 259 Name##Operator k##Name##Operator; |
258 SHARED_OP_LIST(SHARED) | 260 CACHED_OP_LIST(CACHED) |
259 #undef SHARED | 261 #undef CACHED |
260 }; | 262 }; |
261 | 263 |
262 | 264 |
263 static base::LazyInstance<JSOperatorBuilderImpl>::type kImpl = | 265 static base::LazyInstance<JSOperatorGlobalCache>::type kCache = |
264 LAZY_INSTANCE_INITIALIZER; | 266 LAZY_INSTANCE_INITIALIZER; |
265 | 267 |
266 | 268 |
267 JSOperatorBuilder::JSOperatorBuilder(Zone* zone) | 269 JSOperatorBuilder::JSOperatorBuilder(Zone* zone) |
268 : impl_(kImpl.Get()), zone_(zone) {} | 270 : cache_(kCache.Get()), zone_(zone) {} |
269 | 271 |
270 | 272 |
271 #define SHARED(Name, properties, value_input_count, value_output_count) \ | 273 #define CACHED(Name, properties, value_input_count, value_output_count) \ |
272 const Operator* JSOperatorBuilder::Name() { return &impl_.k##Name##Operator; } | 274 const Operator* JSOperatorBuilder::Name() { \ |
273 SHARED_OP_LIST(SHARED) | 275 return &cache_.k##Name##Operator; \ |
274 #undef SHARED | 276 } |
| 277 CACHED_OP_LIST(CACHED) |
| 278 #undef CACHED |
275 | 279 |
276 | 280 |
277 const Operator* JSOperatorBuilder::CallFunction(size_t arity, | 281 const Operator* JSOperatorBuilder::CallFunction(size_t arity, |
278 CallFunctionFlags flags) { | 282 CallFunctionFlags flags) { |
279 CallFunctionParameters parameters(arity, flags); | 283 CallFunctionParameters parameters(arity, flags); |
280 return new (zone()) Operator1<CallFunctionParameters>( | 284 return new (zone()) Operator1<CallFunctionParameters>( // -- |
281 IrOpcode::kJSCallFunction, Operator::kNoProperties, | 285 IrOpcode::kJSCallFunction, Operator::kNoProperties, // opcode |
282 static_cast<int>(parameters.arity()), 1, "JSCallFunction", parameters); | 286 "JSCallFunction", // name |
| 287 parameters.arity(), 1, 1, 1, 1, 0, // inputs/outputs |
| 288 parameters); // parameter |
283 } | 289 } |
284 | 290 |
285 | 291 |
286 const Operator* JSOperatorBuilder::CallRuntime(Runtime::FunctionId id, | 292 const Operator* JSOperatorBuilder::CallRuntime(Runtime::FunctionId id, |
287 size_t arity) { | 293 size_t arity) { |
288 CallRuntimeParameters parameters(id, arity); | 294 CallRuntimeParameters parameters(id, arity); |
289 const Runtime::Function* f = Runtime::FunctionForId(parameters.id()); | 295 const Runtime::Function* f = Runtime::FunctionForId(parameters.id()); |
290 int arguments = static_cast<int>(parameters.arity()); | 296 DCHECK(f->nargs == -1 || f->nargs == static_cast<int>(parameters.arity())); |
291 DCHECK(f->nargs == -1 || f->nargs == arguments); | 297 return new (zone()) Operator1<CallRuntimeParameters>( // -- |
292 return new (zone()) Operator1<CallRuntimeParameters>( | 298 IrOpcode::kJSCallRuntime, Operator::kNoProperties, // opcode |
293 IrOpcode::kJSCallRuntime, Operator::kNoProperties, arguments, | 299 "JSCallRuntime", // name |
294 f->result_size, "JSCallRuntime", parameters); | 300 parameters.arity(), 1, 1, f->result_size, 1, 0, // inputs/outputs |
| 301 parameters); // parameter |
295 } | 302 } |
296 | 303 |
297 | 304 |
298 const Operator* JSOperatorBuilder::CallConstruct(int arguments) { | 305 const Operator* JSOperatorBuilder::CallConstruct(int arguments) { |
299 return new (zone()) | 306 return new (zone()) Operator1<int>( // -- |
300 Operator1<int>(IrOpcode::kJSCallConstruct, Operator::kNoProperties, | 307 IrOpcode::kJSCallConstruct, Operator::kNoProperties, // opcode |
301 arguments, 1, "JSCallConstruct", arguments); | 308 "JSCallConstruct", // name |
| 309 arguments, 1, 1, 1, 1, 0, // counts |
| 310 arguments); // parameter |
302 } | 311 } |
303 | 312 |
304 | 313 |
305 const Operator* JSOperatorBuilder::LoadNamed(const Unique<Name>& name, | 314 const Operator* JSOperatorBuilder::LoadNamed(const Unique<Name>& name, |
306 const VectorSlotPair& feedback, | 315 const VectorSlotPair& feedback, |
307 ContextualMode contextual_mode) { | 316 ContextualMode contextual_mode) { |
308 LoadNamedParameters parameters(name, feedback, contextual_mode); | 317 LoadNamedParameters parameters(name, feedback, contextual_mode); |
309 return new (zone()) Operator1<LoadNamedParameters>( | 318 return new (zone()) Operator1<LoadNamedParameters>( // -- |
310 IrOpcode::kJSLoadNamed, Operator::kNoProperties, 1, 1, "JSLoadNamed", | 319 IrOpcode::kJSLoadNamed, Operator::kNoProperties, // opcode |
311 parameters); | 320 "JSLoadNamed", // name |
| 321 1, 1, 1, 1, 1, 0, // counts |
| 322 parameters); // parameter |
312 } | 323 } |
313 | 324 |
314 | 325 |
315 const Operator* JSOperatorBuilder::LoadProperty( | 326 const Operator* JSOperatorBuilder::LoadProperty( |
316 const VectorSlotPair& feedback) { | 327 const VectorSlotPair& feedback) { |
317 LoadPropertyParameters parameters(feedback); | 328 LoadPropertyParameters parameters(feedback); |
318 return new (zone()) Operator1<LoadPropertyParameters>( | 329 return new (zone()) Operator1<LoadPropertyParameters>( // -- |
319 IrOpcode::kJSLoadProperty, Operator::kNoProperties, 2, 1, | 330 IrOpcode::kJSLoadProperty, Operator::kNoProperties, // opcode |
320 "JSLoadProperty", parameters); | 331 "JSLoadProperty", // name |
| 332 2, 1, 1, 1, 1, 0, // counts |
| 333 parameters); // parameter |
321 } | 334 } |
322 | 335 |
323 | 336 |
324 const Operator* JSOperatorBuilder::StoreProperty(StrictMode strict_mode) { | 337 const Operator* JSOperatorBuilder::StoreProperty(StrictMode strict_mode) { |
325 return new (zone()) | 338 return new (zone()) Operator1<StrictMode>( // -- |
326 Operator1<StrictMode>(IrOpcode::kJSStoreProperty, Operator::kNoProperties, | 339 IrOpcode::kJSStoreProperty, Operator::kNoProperties, // opcode |
327 3, 0, "JSStoreProperty", strict_mode); | 340 "JSStoreProperty", // name |
| 341 3, 1, 1, 0, 1, 0, // counts |
| 342 strict_mode); // parameter |
328 } | 343 } |
329 | 344 |
330 | 345 |
331 const Operator* JSOperatorBuilder::StoreNamed(StrictMode strict_mode, | 346 const Operator* JSOperatorBuilder::StoreNamed(StrictMode strict_mode, |
332 const Unique<Name>& name) { | 347 const Unique<Name>& name) { |
333 StoreNamedParameters parameters(strict_mode, name); | 348 StoreNamedParameters parameters(strict_mode, name); |
334 return new (zone()) Operator1<StoreNamedParameters>( | 349 return new (zone()) Operator1<StoreNamedParameters>( // -- |
335 IrOpcode::kJSStoreNamed, Operator::kNoProperties, 2, 0, "JSStoreNamed", | 350 IrOpcode::kJSStoreNamed, Operator::kNoProperties, // opcode |
336 parameters); | 351 "JSStoreNamed", // name |
| 352 2, 1, 1, 0, 1, 0, // counts |
| 353 parameters); // parameter |
337 } | 354 } |
338 | 355 |
339 | 356 |
340 const Operator* JSOperatorBuilder::DeleteProperty(StrictMode strict_mode) { | 357 const Operator* JSOperatorBuilder::DeleteProperty(StrictMode strict_mode) { |
341 return new (zone()) Operator1<StrictMode>(IrOpcode::kJSDeleteProperty, | 358 return new (zone()) Operator1<StrictMode>( // -- |
342 Operator::kNoProperties, 2, 1, | 359 IrOpcode::kJSDeleteProperty, Operator::kNoProperties, // opcode |
343 "JSDeleteProperty", strict_mode); | 360 "JSDeleteProperty", // name |
| 361 2, 1, 1, 1, 1, 0, // counts |
| 362 strict_mode); // parameter |
344 } | 363 } |
345 | 364 |
346 | 365 |
347 const Operator* JSOperatorBuilder::LoadContext(size_t depth, size_t index, | 366 const Operator* JSOperatorBuilder::LoadContext(size_t depth, size_t index, |
348 bool immutable) { | 367 bool immutable) { |
349 ContextAccess access(depth, index, immutable); | 368 ContextAccess access(depth, index, immutable); |
350 return new (zone()) Operator1<ContextAccess>( | 369 return new (zone()) Operator1<ContextAccess>( // -- |
351 IrOpcode::kJSLoadContext, Operator::kEliminatable | Operator::kNoWrite, 1, | 370 IrOpcode::kJSLoadContext, Operator::kNoWrite, // opcode |
352 1, "JSLoadContext", access); | 371 "JSLoadContext", // name |
| 372 1, 1, 0, 1, 1, 0, // counts |
| 373 access); // parameter |
353 } | 374 } |
354 | 375 |
355 | 376 |
356 const Operator* JSOperatorBuilder::StoreContext(size_t depth, size_t index) { | 377 const Operator* JSOperatorBuilder::StoreContext(size_t depth, size_t index) { |
357 ContextAccess access(depth, index, false); | 378 ContextAccess access(depth, index, false); |
358 return new (zone()) Operator1<ContextAccess>(IrOpcode::kJSStoreContext, | 379 return new (zone()) Operator1<ContextAccess>( // -- |
359 Operator::kNoProperties, 2, 0, | 380 IrOpcode::kJSStoreContext, Operator::kNoRead, // opcode |
360 "JSStoreContext", access); | 381 "JSStoreContext", // name |
| 382 2, 1, 1, 0, 1, 0, // counts |
| 383 access); // parameter |
361 } | 384 } |
362 | 385 |
363 | 386 |
364 const Operator* JSOperatorBuilder::CreateCatchContext( | 387 const Operator* JSOperatorBuilder::CreateCatchContext( |
365 const Unique<String>& name) { | 388 const Unique<String>& name) { |
366 return new (zone()) Operator1<Unique<String>>(IrOpcode::kJSCreateCatchContext, | 389 return new (zone()) Operator1<Unique<String>>( // -- |
367 Operator::kNoProperties, 1, 1, | 390 IrOpcode::kJSCreateCatchContext, Operator::kNoProperties, // opcode |
368 "JSCreateCatchContext", name); | 391 "JSCreateCatchContext", // name |
| 392 1, 1, 1, 1, 1, 0, // counts |
| 393 name); // parameter |
369 } | 394 } |
370 | 395 |
371 } // namespace compiler | 396 } // namespace compiler |
372 } // namespace internal | 397 } // namespace internal |
373 } // namespace v8 | 398 } // namespace v8 |
OLD | NEW |