Index: src/hydrogen.cc |
diff --git a/src/hydrogen.cc b/src/hydrogen.cc |
index 142c92171048e44b92b22998da9be366c4ae9cec..9a5028f77d3369182fa26f2df9cd3eed16cce84d 100644 |
--- a/src/hydrogen.cc |
+++ b/src/hydrogen.cc |
@@ -1557,6 +1557,77 @@ HValue* HGraphBuilder::BuildUncheckedDictionaryElementLoad(HValue* receiver, |
} |
+HValue* HGraphBuilder::BuildRegExpConstructResult(HValue* length, |
+ HValue* index, |
+ HValue* input) { |
+ NoObservableSideEffectsScope scope(this); |
+ |
+ // Compute the size of the RegExpResult followed by FixedArray with length. |
+ HValue* size = length; |
mvstanton
2014/01/29 08:51:16
Shouldn't you verify length is a smi?
Benedikt Meurer
2014/01/29 08:55:19
Crankshaft generates an HChange (s->t) implicitly.
|
+ size = AddUncasted<HShl>(size, Add<HConstant>(kPointerSizeLog2)); |
+ size = AddUncasted<HAdd>(size, Add<HConstant>(static_cast<int32_t>( |
+ JSRegExpResult::kSize + FixedArray::kHeaderSize))); |
+ |
+ // Make sure size does not exceeds max regular heap object size. |
+ Add<HBoundsCheck>(size, Add<HConstant>(Page::kMaxRegularHeapObjectSize)); |
+ |
+ // Allocate the JSRegExpResult and the FixedArray in one step. |
+ HValue* result = Add<HAllocate>( |
+ size, HType::JSArray(), NOT_TENURED, JS_ARRAY_TYPE); |
mvstanton
2014/01/29 08:51:16
Actually, why not let allocation folding take care
Benedikt Meurer
2014/01/29 08:55:19
That doesn't work well with variable sized allocat
|
+ |
+ // Determine the elements FixedArray. |
+ HValue* elements = Add<HInnerAllocatedObject>( |
+ result, Add<HConstant>(JSRegExpResult::kSize)); |
+ |
+ // Initialize the JSRegExpResult header. |
+ HValue* global_object = Add<HLoadNamedField>( |
+ context(), HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); |
mvstanton
2014/01/29 08:51:16
Any reason to use this instead of HGlobalObject? D
Benedikt Meurer
2014/01/29 08:55:19
HGlobalObject is gone. :-)
|
+ HValue* native_context = Add<HLoadNamedField>( |
+ global_object, HObjectAccess::ForGlobalObjectNativeContext()); |
+ AddStoreMapNoWriteBarrier(result, Add<HLoadNamedField>( |
+ native_context, HObjectAccess::ForContextSlot( |
+ Context::REGEXP_RESULT_MAP_INDEX))); |
+ Add<HStoreNamedField>( |
+ result, |
+ HObjectAccess::ForJSArrayOffset(JSArray::kPropertiesOffset), |
+ Add<HConstant>(isolate()->factory()->empty_fixed_array())); |
+ Add<HStoreNamedField>( |
+ result, |
+ HObjectAccess::ForJSArrayOffset(JSArray::kElementsOffset), |
+ elements); |
+ Add<HStoreNamedField>( |
+ result, |
+ HObjectAccess::ForJSArrayOffset(JSArray::kLengthOffset), |
+ length); |
+ |
+ // Initialize the additional fields. |
+ Add<HStoreNamedField>( |
+ result, |
+ HObjectAccess::ForJSArrayOffset(JSRegExpResult::kIndexOffset), |
+ index); |
+ Add<HStoreNamedField>( |
+ result, |
+ HObjectAccess::ForJSArrayOffset(JSRegExpResult::kInputOffset), |
+ input); |
+ |
+ // Initialize the elements header. |
+ AddStoreMapConstantNoWriteBarrier(elements, |
+ isolate()->factory()->fixed_array_map()); |
+ Add<HStoreNamedField>(elements, HObjectAccess::ForFixedArrayLength(), length); |
+ |
+ // Initialize the elements contents with undefined. |
+ LoopBuilder loop(this, context(), LoopBuilder::kPostIncrement); |
+ index = loop.BeginBody(graph()->GetConstant0(), length, Token::LT); |
+ { |
+ Add<HStoreKeyed>(elements, index, graph()->GetConstantUndefined(), |
+ FAST_ELEMENTS); |
+ } |
+ loop.EndBody(); |
+ |
+ return result; |
+} |
+ |
+ |
HValue* HGraphBuilder::BuildNumberToString(HValue* object, Type* type) { |
NoObservableSideEffectsScope scope(this); |
@@ -10347,10 +10418,14 @@ void HOptimizedGraphBuilder::GenerateRegExpExec(CallRuntime* call) { |
// Construct a RegExp exec result with two in-object properties. |
void HOptimizedGraphBuilder::GenerateRegExpConstructResult(CallRuntime* call) { |
ASSERT_EQ(3, call->arguments()->length()); |
- CHECK_ALIVE(VisitArgumentList(call->arguments())); |
- HCallStub* result = New<HCallStub>(CodeStub::RegExpConstructResult, 3); |
- Drop(3); |
- return ast_context()->ReturnInstruction(result, call->id()); |
+ CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
+ CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); |
+ CHECK_ALIVE(VisitForValue(call->arguments()->at(2))); |
+ HValue* input = Pop(); |
+ HValue* index = Pop(); |
+ HValue* length = Pop(); |
+ HValue* result = BuildRegExpConstructResult(length, index, input); |
+ return ast_context()->ReturnValue(result); |
} |