| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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/code-stubs.h" | 5 #include "src/code-stubs.h" |
| 6 | 6 |
| 7 #include <sstream> | 7 #include <sstream> |
| 8 | 8 |
| 9 #include "src/ast/ast.h" | 9 #include "src/ast/ast.h" |
| 10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
| (...skipping 2312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2323 { | 2323 { |
| 2324 var_result.Bind( | 2324 var_result.Bind( |
| 2325 assembler.CallRuntime(Runtime::kGetProperty, context, object, key)); | 2325 assembler.CallRuntime(Runtime::kGetProperty, context, object, key)); |
| 2326 assembler.Goto(&end); | 2326 assembler.Goto(&end); |
| 2327 } | 2327 } |
| 2328 | 2328 |
| 2329 assembler.Bind(&end); | 2329 assembler.Bind(&end); |
| 2330 assembler.Return(var_result.value()); | 2330 assembler.Return(var_result.value()); |
| 2331 } | 2331 } |
| 2332 | 2332 |
| 2333 // static | |
| 2334 compiler::Node* FastNewClosureStub::Generate(CodeStubAssembler* assembler, | |
| 2335 compiler::Node* shared_info, | |
| 2336 compiler::Node* context) { | |
| 2337 typedef compiler::Node Node; | |
| 2338 typedef compiler::CodeAssembler::Label Label; | |
| 2339 typedef compiler::CodeAssembler::Variable Variable; | |
| 2340 | |
| 2341 Isolate* isolate = assembler->isolate(); | |
| 2342 Factory* factory = assembler->isolate()->factory(); | |
| 2343 assembler->IncrementCounter(isolate->counters()->fast_new_closure_total(), 1); | |
| 2344 | |
| 2345 // Create a new closure from the given function info in new space | |
| 2346 Node* result = assembler->Allocate(JSFunction::kSize); | |
| 2347 | |
| 2348 // Calculate the index of the map we should install on the function based on | |
| 2349 // the FunctionKind and LanguageMode of the function. | |
| 2350 // Note: Must be kept in sync with Context::FunctionMapIndex | |
| 2351 Node* compiler_hints = assembler->LoadObjectField( | |
| 2352 shared_info, SharedFunctionInfo::kCompilerHintsOffset, | |
| 2353 MachineType::Uint32()); | |
| 2354 Node* is_strict = assembler->Word32And( | |
| 2355 compiler_hints, | |
| 2356 assembler->Int32Constant(1 << SharedFunctionInfo::kStrictModeBit)); | |
| 2357 | |
| 2358 Label if_normal(assembler), if_generator(assembler), if_async(assembler), | |
| 2359 if_class_constructor(assembler), if_function_without_prototype(assembler), | |
| 2360 load_map(assembler); | |
| 2361 Variable map_index(assembler, MachineType::PointerRepresentation()); | |
| 2362 | |
| 2363 STATIC_ASSERT(FunctionKind::kNormalFunction == 0); | |
| 2364 Node* is_not_normal = assembler->Word32And( | |
| 2365 compiler_hints, | |
| 2366 assembler->Int32Constant(SharedFunctionInfo::kAllFunctionKindBitsMask)); | |
| 2367 assembler->GotoUnless(is_not_normal, &if_normal); | |
| 2368 | |
| 2369 Node* is_generator = assembler->Word32And( | |
| 2370 compiler_hints, | |
| 2371 assembler->Int32Constant(FunctionKind::kGeneratorFunction | |
| 2372 << SharedFunctionInfo::kFunctionKindShift)); | |
| 2373 assembler->GotoIf(is_generator, &if_generator); | |
| 2374 | |
| 2375 Node* is_async = assembler->Word32And( | |
| 2376 compiler_hints, | |
| 2377 assembler->Int32Constant(FunctionKind::kAsyncFunction | |
| 2378 << SharedFunctionInfo::kFunctionKindShift)); | |
| 2379 assembler->GotoIf(is_async, &if_async); | |
| 2380 | |
| 2381 Node* is_class_constructor = assembler->Word32And( | |
| 2382 compiler_hints, | |
| 2383 assembler->Int32Constant(FunctionKind::kClassConstructor | |
| 2384 << SharedFunctionInfo::kFunctionKindShift)); | |
| 2385 assembler->GotoIf(is_class_constructor, &if_class_constructor); | |
| 2386 | |
| 2387 if (FLAG_debug_code) { | |
| 2388 // Function must be a function without a prototype. | |
| 2389 CSA_ASSERT(assembler, assembler->Word32And( | |
| 2390 compiler_hints, | |
| 2391 assembler->Int32Constant( | |
| 2392 (FunctionKind::kAccessorFunction | | |
| 2393 FunctionKind::kArrowFunction | | |
| 2394 FunctionKind::kConciseMethod) | |
| 2395 << SharedFunctionInfo::kFunctionKindShift))); | |
| 2396 } | |
| 2397 assembler->Goto(&if_function_without_prototype); | |
| 2398 | |
| 2399 assembler->Bind(&if_normal); | |
| 2400 { | |
| 2401 map_index.Bind(assembler->SelectIntPtrConstant( | |
| 2402 is_strict, Context::STRICT_FUNCTION_MAP_INDEX, | |
| 2403 Context::SLOPPY_FUNCTION_MAP_INDEX)); | |
| 2404 assembler->Goto(&load_map); | |
| 2405 } | |
| 2406 | |
| 2407 assembler->Bind(&if_generator); | |
| 2408 { | |
| 2409 map_index.Bind(assembler->SelectIntPtrConstant( | |
| 2410 is_strict, Context::STRICT_GENERATOR_FUNCTION_MAP_INDEX, | |
| 2411 Context::SLOPPY_GENERATOR_FUNCTION_MAP_INDEX)); | |
| 2412 assembler->Goto(&load_map); | |
| 2413 } | |
| 2414 | |
| 2415 assembler->Bind(&if_async); | |
| 2416 { | |
| 2417 map_index.Bind(assembler->SelectIntPtrConstant( | |
| 2418 is_strict, Context::STRICT_ASYNC_FUNCTION_MAP_INDEX, | |
| 2419 Context::SLOPPY_ASYNC_FUNCTION_MAP_INDEX)); | |
| 2420 assembler->Goto(&load_map); | |
| 2421 } | |
| 2422 | |
| 2423 assembler->Bind(&if_class_constructor); | |
| 2424 { | |
| 2425 map_index.Bind( | |
| 2426 assembler->IntPtrConstant(Context::CLASS_FUNCTION_MAP_INDEX)); | |
| 2427 assembler->Goto(&load_map); | |
| 2428 } | |
| 2429 | |
| 2430 assembler->Bind(&if_function_without_prototype); | |
| 2431 { | |
| 2432 map_index.Bind(assembler->IntPtrConstant( | |
| 2433 Context::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX)); | |
| 2434 assembler->Goto(&load_map); | |
| 2435 } | |
| 2436 | |
| 2437 assembler->Bind(&load_map); | |
| 2438 | |
| 2439 // Get the function map in the current native context and set that | |
| 2440 // as the map of the allocated object. | |
| 2441 Node* native_context = assembler->LoadNativeContext(context); | |
| 2442 Node* map_slot_value = | |
| 2443 assembler->LoadFixedArrayElement(native_context, map_index.value()); | |
| 2444 assembler->StoreMapNoWriteBarrier(result, map_slot_value); | |
| 2445 | |
| 2446 // Initialize the rest of the function. | |
| 2447 Node* empty_fixed_array = | |
| 2448 assembler->HeapConstant(factory->empty_fixed_array()); | |
| 2449 Node* empty_literals_array = | |
| 2450 assembler->HeapConstant(factory->empty_literals_array()); | |
| 2451 assembler->StoreObjectFieldNoWriteBarrier(result, JSObject::kPropertiesOffset, | |
| 2452 empty_fixed_array); | |
| 2453 assembler->StoreObjectFieldNoWriteBarrier(result, JSObject::kElementsOffset, | |
| 2454 empty_fixed_array); | |
| 2455 assembler->StoreObjectFieldNoWriteBarrier(result, JSFunction::kLiteralsOffset, | |
| 2456 empty_literals_array); | |
| 2457 assembler->StoreObjectFieldNoWriteBarrier( | |
| 2458 result, JSFunction::kPrototypeOrInitialMapOffset, | |
| 2459 assembler->TheHoleConstant()); | |
| 2460 assembler->StoreObjectFieldNoWriteBarrier( | |
| 2461 result, JSFunction::kSharedFunctionInfoOffset, shared_info); | |
| 2462 assembler->StoreObjectFieldNoWriteBarrier(result, JSFunction::kContextOffset, | |
| 2463 context); | |
| 2464 Handle<Code> lazy_builtin_handle( | |
| 2465 assembler->isolate()->builtins()->builtin(Builtins::kCompileLazy)); | |
| 2466 Node* lazy_builtin = assembler->HeapConstant(lazy_builtin_handle); | |
| 2467 Node* lazy_builtin_entry = assembler->IntPtrAdd( | |
| 2468 assembler->BitcastTaggedToWord(lazy_builtin), | |
| 2469 assembler->IntPtrConstant(Code::kHeaderSize - kHeapObjectTag)); | |
| 2470 assembler->StoreObjectFieldNoWriteBarrier( | |
| 2471 result, JSFunction::kCodeEntryOffset, lazy_builtin_entry, | |
| 2472 MachineType::PointerRepresentation()); | |
| 2473 assembler->StoreObjectFieldNoWriteBarrier(result, | |
| 2474 JSFunction::kNextFunctionLinkOffset, | |
| 2475 assembler->UndefinedConstant()); | |
| 2476 | |
| 2477 return result; | |
| 2478 } | |
| 2479 | |
| 2480 void FastNewClosureStub::GenerateAssembly( | |
| 2481 compiler::CodeAssemblerState* state) const { | |
| 2482 typedef compiler::Node Node; | |
| 2483 CodeStubAssembler assembler(state); | |
| 2484 Node* shared = assembler.Parameter(Descriptor::kSharedFunctionInfo); | |
| 2485 Node* context = assembler.Parameter(Descriptor::kContext); | |
| 2486 assembler.Return(Generate(&assembler, shared, context)); | |
| 2487 } | |
| 2488 | 2333 |
| 2489 // static | 2334 // static |
| 2490 int FastNewFunctionContextStub::MaximumSlots() { | 2335 int FastNewFunctionContextStub::MaximumSlots() { |
| 2491 return FLAG_test_small_max_function_context_stub_size ? kSmallMaximumSlots | 2336 return FLAG_test_small_max_function_context_stub_size ? kSmallMaximumSlots |
| 2492 : kMaximumSlots; | 2337 : kMaximumSlots; |
| 2493 } | 2338 } |
| 2494 | 2339 |
| 2495 // static | 2340 // static |
| 2496 compiler::Node* FastNewFunctionContextStub::Generate( | 2341 compiler::Node* FastNewFunctionContextStub::Generate( |
| 2497 CodeStubAssembler* assembler, compiler::Node* function, | 2342 CodeStubAssembler* assembler, compiler::Node* function, |
| (...skipping 620 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3118 } | 2963 } |
| 3119 | 2964 |
| 3120 ArrayConstructorStub::ArrayConstructorStub(Isolate* isolate) | 2965 ArrayConstructorStub::ArrayConstructorStub(Isolate* isolate) |
| 3121 : PlatformCodeStub(isolate) {} | 2966 : PlatformCodeStub(isolate) {} |
| 3122 | 2967 |
| 3123 InternalArrayConstructorStub::InternalArrayConstructorStub(Isolate* isolate) | 2968 InternalArrayConstructorStub::InternalArrayConstructorStub(Isolate* isolate) |
| 3124 : PlatformCodeStub(isolate) {} | 2969 : PlatformCodeStub(isolate) {} |
| 3125 | 2970 |
| 3126 } // namespace internal | 2971 } // namespace internal |
| 3127 } // namespace v8 | 2972 } // namespace v8 |
| OLD | NEW |