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 static inline size_t CE(Operator::Properties properties) { |
251 #define SHARED(Name, properties, value_input_count, value_output_count) \ | 251 return (properties & Operator::kPure) == Operator::kPure ? 0 : 1; |
252 struct Name##Operator FINAL : public SimpleOperator { \ | 252 } |
253 Name##Operator() \ | 253 |
254 : SimpleOperator(IrOpcode::kJS##Name, properties, value_input_count, \ | 254 |
255 value_output_count, "JS" #Name) {} \ | 255 struct JSOperatorGlobalCache FINAL { |
256 }; \ | 256 #define CACHED(Name, properties, value_input_count, value_output_count) \ |
| 257 struct Name##Operator FINAL : public Operator { \ |
| 258 Name##Operator() \ |
| 259 : Operator(IrOpcode::kJS##Name, properties, "JS" #Name, \ |
| 260 value_input_count, CE(properties), CE(properties), \ |
| 261 value_output_count, CE(properties), 0) {} \ |
| 262 }; \ |
257 Name##Operator k##Name##Operator; | 263 Name##Operator k##Name##Operator; |
258 SHARED_OP_LIST(SHARED) | 264 CACHED_OP_LIST(CACHED) |
259 #undef SHARED | 265 #undef CACHED |
260 }; | 266 }; |
261 | 267 |
262 | 268 |
263 static base::LazyInstance<JSOperatorBuilderImpl>::type kImpl = | 269 static base::LazyInstance<JSOperatorGlobalCache>::type kCache = |
264 LAZY_INSTANCE_INITIALIZER; | 270 LAZY_INSTANCE_INITIALIZER; |
265 | 271 |
266 | 272 |
267 JSOperatorBuilder::JSOperatorBuilder(Zone* zone) | 273 JSOperatorBuilder::JSOperatorBuilder(Zone* zone) |
268 : impl_(kImpl.Get()), zone_(zone) {} | 274 : cache_(kCache.Get()), zone_(zone) {} |
269 | 275 |
270 | 276 |
271 #define SHARED(Name, properties, value_input_count, value_output_count) \ | 277 #define CACHED(Name, properties, value_input_count, value_output_count) \ |
272 const Operator* JSOperatorBuilder::Name() { return &impl_.k##Name##Operator; } | 278 const Operator* JSOperatorBuilder::Name() { \ |
273 SHARED_OP_LIST(SHARED) | 279 return &cache_.k##Name##Operator; \ |
274 #undef SHARED | 280 } |
| 281 CACHED_OP_LIST(CACHED) |
| 282 #undef CACHED |
275 | 283 |
276 | 284 |
277 const Operator* JSOperatorBuilder::CallFunction(size_t arity, | 285 const Operator* JSOperatorBuilder::CallFunction(size_t arity, |
278 CallFunctionFlags flags) { | 286 CallFunctionFlags flags) { |
279 CallFunctionParameters parameters(arity, flags); | 287 CallFunctionParameters parameters(arity, flags); |
280 return new (zone()) Operator1<CallFunctionParameters>( | 288 return new (zone()) Operator1<CallFunctionParameters>( // -- |
281 IrOpcode::kJSCallFunction, Operator::kNoProperties, | 289 IrOpcode::kJSCallFunction, Operator::kNoProperties, // opcode |
282 static_cast<int>(parameters.arity()), 1, "JSCallFunction", parameters); | 290 "JSCallFunction", // name |
| 291 parameters.arity(), 1, 1, 1, 1, 0, // inputs/outputs |
| 292 parameters); // parameter |
283 } | 293 } |
284 | 294 |
285 | 295 |
286 const Operator* JSOperatorBuilder::CallRuntime(Runtime::FunctionId id, | 296 const Operator* JSOperatorBuilder::CallRuntime(Runtime::FunctionId id, |
287 size_t arity) { | 297 size_t arity) { |
288 CallRuntimeParameters parameters(id, arity); | 298 CallRuntimeParameters parameters(id, arity); |
289 const Runtime::Function* f = Runtime::FunctionForId(parameters.id()); | 299 const Runtime::Function* f = Runtime::FunctionForId(parameters.id()); |
290 int arguments = static_cast<int>(parameters.arity()); | 300 int arguments = static_cast<int>(parameters.arity()); |
291 DCHECK(f->nargs == -1 || f->nargs == arguments); | 301 DCHECK(f->nargs == -1 || f->nargs == arguments); |
292 return new (zone()) Operator1<CallRuntimeParameters>( | 302 return new (zone()) Operator1<CallRuntimeParameters>( // -- |
293 IrOpcode::kJSCallRuntime, Operator::kNoProperties, arguments, | 303 IrOpcode::kJSCallRuntime, Operator::kNoProperties, // opcode |
294 f->result_size, "JSCallRuntime", parameters); | 304 "JSCallRuntime", // name |
| 305 parameters.arity(), 1, 1, f->result_size, 1, 0, // inputs/outputs |
| 306 parameters); // parameter |
295 } | 307 } |
296 | 308 |
297 | 309 |
298 const Operator* JSOperatorBuilder::CallConstruct(int arguments) { | 310 const Operator* JSOperatorBuilder::CallConstruct(int arguments) { |
299 return new (zone()) | 311 return new (zone()) Operator1<int>( // -- |
300 Operator1<int>(IrOpcode::kJSCallConstruct, Operator::kNoProperties, | 312 IrOpcode::kJSCallConstruct, Operator::kNoProperties, // opcode |
301 arguments, 1, "JSCallConstruct", arguments); | 313 "JSCallConstruct", // name |
| 314 arguments, 1, 1, 1, 1, 0, // counts |
| 315 arguments); // parameter |
302 } | 316 } |
303 | 317 |
304 | 318 |
305 const Operator* JSOperatorBuilder::LoadNamed(const Unique<Name>& name, | 319 const Operator* JSOperatorBuilder::LoadNamed(const Unique<Name>& name, |
306 const VectorSlotPair& feedback, | 320 const VectorSlotPair& feedback, |
307 ContextualMode contextual_mode) { | 321 ContextualMode contextual_mode) { |
308 LoadNamedParameters parameters(name, feedback, contextual_mode); | 322 LoadNamedParameters parameters(name, feedback, contextual_mode); |
309 return new (zone()) Operator1<LoadNamedParameters>( | 323 return new (zone()) Operator1<LoadNamedParameters>( // -- |
310 IrOpcode::kJSLoadNamed, Operator::kNoProperties, 1, 1, "JSLoadNamed", | 324 IrOpcode::kJSLoadNamed, Operator::kNoProperties, // opcode |
311 parameters); | 325 "JSLoadNamed", // name |
| 326 1, 1, 1, 1, 1, 0, // counts |
| 327 parameters); // parameter |
312 } | 328 } |
313 | 329 |
314 | 330 |
315 const Operator* JSOperatorBuilder::LoadProperty( | 331 const Operator* JSOperatorBuilder::LoadProperty( |
316 const VectorSlotPair& feedback) { | 332 const VectorSlotPair& feedback) { |
317 LoadPropertyParameters parameters(feedback); | 333 LoadPropertyParameters parameters(feedback); |
318 return new (zone()) Operator1<LoadPropertyParameters>( | 334 return new (zone()) Operator1<LoadPropertyParameters>( // -- |
319 IrOpcode::kJSLoadProperty, Operator::kNoProperties, 2, 1, | 335 IrOpcode::kJSLoadProperty, Operator::kNoProperties, // opcode |
320 "JSLoadProperty", parameters); | 336 "JSLoadProperty", // name |
| 337 2, 1, 1, 1, 1, 0, // counts |
| 338 parameters); // parameter |
321 } | 339 } |
322 | 340 |
323 | 341 |
324 const Operator* JSOperatorBuilder::StoreProperty(StrictMode strict_mode) { | 342 const Operator* JSOperatorBuilder::StoreProperty(StrictMode strict_mode) { |
325 return new (zone()) | 343 return new (zone()) Operator1<StrictMode>( // -- |
326 Operator1<StrictMode>(IrOpcode::kJSStoreProperty, Operator::kNoProperties, | 344 IrOpcode::kJSStoreProperty, Operator::kNoProperties, // opcode |
327 3, 0, "JSStoreProperty", strict_mode); | 345 "JSStoreProperty", // name |
| 346 3, 1, 1, 0, 1, 0, // counts |
| 347 strict_mode); // parameter |
328 } | 348 } |
329 | 349 |
330 | 350 |
331 const Operator* JSOperatorBuilder::StoreNamed(StrictMode strict_mode, | 351 const Operator* JSOperatorBuilder::StoreNamed(StrictMode strict_mode, |
332 const Unique<Name>& name) { | 352 const Unique<Name>& name) { |
333 StoreNamedParameters parameters(strict_mode, name); | 353 StoreNamedParameters parameters(strict_mode, name); |
334 return new (zone()) Operator1<StoreNamedParameters>( | 354 return new (zone()) Operator1<StoreNamedParameters>( // -- |
335 IrOpcode::kJSStoreNamed, Operator::kNoProperties, 2, 0, "JSStoreNamed", | 355 IrOpcode::kJSStoreNamed, Operator::kNoProperties, // opcode |
336 parameters); | 356 "JSStoreNamed", // name |
| 357 2, 1, 1, 0, 1, 0, // counts |
| 358 parameters); // parameter |
337 } | 359 } |
338 | 360 |
339 | 361 |
340 const Operator* JSOperatorBuilder::DeleteProperty(StrictMode strict_mode) { | 362 const Operator* JSOperatorBuilder::DeleteProperty(StrictMode strict_mode) { |
341 return new (zone()) Operator1<StrictMode>(IrOpcode::kJSDeleteProperty, | 363 return new (zone()) Operator1<StrictMode>( // -- |
342 Operator::kNoProperties, 2, 1, | 364 IrOpcode::kJSDeleteProperty, Operator::kNoProperties, // opcode |
343 "JSDeleteProperty", strict_mode); | 365 "JSDeleteProperty", // name |
| 366 2, 1, 1, 1, 1, 0, // counts |
| 367 strict_mode); // parameter |
344 } | 368 } |
345 | 369 |
346 | 370 |
347 const Operator* JSOperatorBuilder::LoadContext(size_t depth, size_t index, | 371 const Operator* JSOperatorBuilder::LoadContext(size_t depth, size_t index, |
348 bool immutable) { | 372 bool immutable) { |
349 ContextAccess access(depth, index, immutable); | 373 ContextAccess access(depth, index, immutable); |
350 return new (zone()) Operator1<ContextAccess>( | 374 return new (zone()) Operator1<ContextAccess>( // -- |
351 IrOpcode::kJSLoadContext, Operator::kEliminatable | Operator::kNoWrite, 1, | 375 IrOpcode::kJSLoadContext, Operator::kNoWrite, // opcode |
352 1, "JSLoadContext", access); | 376 "JSLoadContext", // name |
| 377 1, 1, 0, 1, 1, 0, // counts |
| 378 access); // parameter |
353 } | 379 } |
354 | 380 |
355 | 381 |
356 const Operator* JSOperatorBuilder::StoreContext(size_t depth, size_t index) { | 382 const Operator* JSOperatorBuilder::StoreContext(size_t depth, size_t index) { |
357 ContextAccess access(depth, index, false); | 383 ContextAccess access(depth, index, false); |
358 return new (zone()) Operator1<ContextAccess>(IrOpcode::kJSStoreContext, | 384 return new (zone()) Operator1<ContextAccess>( // -- |
359 Operator::kNoProperties, 2, 0, | 385 IrOpcode::kJSStoreContext, Operator::kNoRead, // opcode |
360 "JSStoreContext", access); | 386 "JSStoreContext", // name |
| 387 2, 1, 1, 0, 1, 0, // counts |
| 388 access); // parameter |
361 } | 389 } |
362 | 390 |
363 | 391 |
364 const Operator* JSOperatorBuilder::CreateCatchContext( | 392 const Operator* JSOperatorBuilder::CreateCatchContext( |
365 const Unique<String>& name) { | 393 const Unique<String>& name) { |
366 return new (zone()) Operator1<Unique<String>>(IrOpcode::kJSCreateCatchContext, | 394 return new (zone()) Operator1<Unique<String>>( // -- |
367 Operator::kNoProperties, 1, 1, | 395 IrOpcode::kJSCreateCatchContext, Operator::kNoProperties, // opcode |
368 "JSCreateCatchContext", name); | 396 "JSCreateCatchContext", // name |
| 397 1, 1, 1, 1, 1, 0, // counts |
| 398 name); // parameter |
369 } | 399 } |
370 | 400 |
371 } // namespace compiler | 401 } // namespace compiler |
372 } // namespace internal | 402 } // namespace internal |
373 } // namespace v8 | 403 } // namespace v8 |
OLD | NEW |