| 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 |